226 lines
7.1 KiB
C#
226 lines
7.1 KiB
C#
///Credit ChoMPHi
|
|
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using UnityEngine.UI.Extensions.Tweens;
|
|
|
|
namespace UnityEngine.UI.Extensions
|
|
{
|
|
[RequireComponent(typeof(RectTransform), typeof(LayoutElement))]
|
|
[AddComponentMenu("UI/Extensions/Accordion/Accordion Element")]
|
|
public class AccordionElement : Toggle
|
|
{
|
|
|
|
[SerializeField] private float m_MinHeight = 18f;
|
|
|
|
public float MinHeight => m_MinHeight;
|
|
|
|
[SerializeField] private float m_MinWidth = 40f;
|
|
|
|
public float MinWidth => m_MinWidth;
|
|
|
|
private Accordion m_Accordion;
|
|
private RectTransform m_RectTransform;
|
|
private LayoutElement m_LayoutElement;
|
|
|
|
[NonSerialized]
|
|
private readonly TweenRunner<FloatTween> m_FloatTweenRunner;
|
|
|
|
protected AccordionElement()
|
|
{
|
|
if (this.m_FloatTweenRunner == null)
|
|
this.m_FloatTweenRunner = new TweenRunner<FloatTween>();
|
|
|
|
this.m_FloatTweenRunner.Init(this);
|
|
}
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
base.transition = Transition.None;
|
|
base.toggleTransition = ToggleTransition.None;
|
|
this.m_Accordion = this.gameObject.GetComponentInParent<Accordion>();
|
|
this.m_RectTransform = this.transform as RectTransform;
|
|
this.m_LayoutElement = this.gameObject.GetComponent<LayoutElement>();
|
|
this.onValueChanged.AddListener(OnValueChanged);
|
|
}
|
|
|
|
private new IEnumerator Start()
|
|
{
|
|
base.Start();
|
|
yield return new WaitForEndOfFrame(); // Wait for the first frame
|
|
OnValueChanged(this.isOn);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
protected override void OnValidate()
|
|
{
|
|
base.OnValidate();
|
|
this.m_Accordion = this.gameObject.GetComponentInParent<Accordion>();
|
|
|
|
if (this.group == null)
|
|
{
|
|
ToggleGroup tg = this.GetComponentInParent<ToggleGroup>();
|
|
|
|
if (tg != null)
|
|
{
|
|
this.group = tg;
|
|
}
|
|
}
|
|
|
|
LayoutElement le = this.gameObject.GetComponent<LayoutElement>();
|
|
|
|
if (le != null && m_Accordion != null)
|
|
{
|
|
if (this.isOn)
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
le.preferredHeight = -1f;
|
|
}
|
|
else
|
|
{
|
|
le.preferredWidth = -1f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
le.preferredHeight = this.m_MinHeight;
|
|
}
|
|
else
|
|
{
|
|
le.preferredWidth = this.m_MinWidth;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public void OnValueChanged(bool state)
|
|
{
|
|
if (this.m_LayoutElement == null)
|
|
return;
|
|
|
|
Accordion.Transition transition = (this.m_Accordion != null) ? this.m_Accordion.transition : Accordion.Transition.Instant;
|
|
|
|
if (transition == Accordion.Transition.Instant && m_Accordion != null)
|
|
{
|
|
if (state)
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
this.m_LayoutElement.preferredHeight = -1f;
|
|
}
|
|
else
|
|
{
|
|
this.m_LayoutElement.preferredWidth = -1f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
this.m_LayoutElement.preferredHeight = this.m_MinHeight;
|
|
}
|
|
else
|
|
{
|
|
this.m_LayoutElement.preferredWidth = this.m_MinWidth;
|
|
}
|
|
}
|
|
}
|
|
else if (transition == Accordion.Transition.Tween)
|
|
{
|
|
if (state)
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
this.StartTween(this.m_MinHeight, this.GetExpandedHeight());
|
|
}
|
|
else
|
|
{
|
|
this.StartTween(this.m_MinWidth, this.GetExpandedWidth());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
this.StartTween(this.m_RectTransform.rect.height, this.m_MinHeight);
|
|
}
|
|
else
|
|
{
|
|
this.StartTween(this.m_RectTransform.rect.width, this.m_MinWidth);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected float GetExpandedHeight()
|
|
{
|
|
if (this.m_LayoutElement == null)
|
|
return this.m_MinHeight;
|
|
|
|
float originalPrefH = this.m_LayoutElement.preferredHeight;
|
|
this.m_LayoutElement.preferredHeight = -1f;
|
|
float h = LayoutUtility.GetPreferredHeight(this.m_RectTransform);
|
|
this.m_LayoutElement.preferredHeight = originalPrefH;
|
|
|
|
return h;
|
|
}
|
|
|
|
protected float GetExpandedWidth()
|
|
{
|
|
if (this.m_LayoutElement == null)
|
|
return this.m_MinWidth;
|
|
|
|
float originalPrefW = this.m_LayoutElement.preferredWidth;
|
|
this.m_LayoutElement.preferredWidth = -1f;
|
|
float w = LayoutUtility.GetPreferredWidth(this.m_RectTransform);
|
|
this.m_LayoutElement.preferredWidth = originalPrefW;
|
|
|
|
return w;
|
|
}
|
|
|
|
protected void StartTween(float startFloat, float targetFloat)
|
|
{
|
|
float duration = (this.m_Accordion != null) ? this.m_Accordion.transitionDuration : 0.3f;
|
|
|
|
FloatTween info = new FloatTween
|
|
{
|
|
duration = duration,
|
|
startFloat = startFloat,
|
|
targetFloat = targetFloat
|
|
};
|
|
if (m_Accordion.ExpandVerticval)
|
|
{
|
|
info.AddOnChangedCallback(SetHeight);
|
|
}
|
|
else
|
|
{
|
|
info.AddOnChangedCallback(SetWidth);
|
|
}
|
|
info.ignoreTimeScale = true;
|
|
this.m_FloatTweenRunner.StartTween(info);
|
|
}
|
|
|
|
protected void SetHeight(float height)
|
|
{
|
|
if (this.m_LayoutElement == null)
|
|
return;
|
|
|
|
this.m_LayoutElement.preferredHeight = height;
|
|
}
|
|
|
|
protected void SetWidth(float width)
|
|
{
|
|
if (this.m_LayoutElement == null)
|
|
return;
|
|
|
|
this.m_LayoutElement.preferredWidth = width;
|
|
}
|
|
}
|
|
} |