114 lines
3.1 KiB
C#
114 lines
3.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Cryville.Common.Unity.UI {
|
|
/// <summary>
|
|
/// A <see cref="ILayoutElement" /> that takes the length of one axis to compute the preferred length of the other axis with respect to a aspect ratio.
|
|
/// </summary>
|
|
[AddComponentMenu("Layout/Aspect Ratio Layout Element")]
|
|
[ExecuteAlways]
|
|
public class AspectRatioLayoutElement : UIBehaviour, ILayoutElement {
|
|
[SerializeField]
|
|
[Tooltip("The aspect ratio. Width divided by height.")]
|
|
private float m_aspectRatio = 1;
|
|
/// <summary>
|
|
/// The aspect ratio. Width divided by height.
|
|
/// </summary>
|
|
public float AspectRatio {
|
|
get { return m_aspectRatio; }
|
|
set { SetProperty(ref m_aspectRatio, value); }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Tooltip("Whether to compute the length of the y axis.")]
|
|
private bool m_isVertical = false;
|
|
/// <summary>
|
|
/// Whether to compute the length of the y axis.
|
|
/// </summary>
|
|
public bool IsVertical {
|
|
get { return m_isVertical; }
|
|
set { SetProperty(ref m_isVertical, value); }
|
|
}
|
|
|
|
private void SetProperty<T>(ref T prop, T value) {
|
|
if (Equals(prop, value)) return;
|
|
prop = value;
|
|
SetDirty();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public float minWidth {
|
|
get {
|
|
return m_isVertical ? -1 : (transform as RectTransform).rect.height * m_aspectRatio;
|
|
}
|
|
}
|
|
/// <inheritdoc />
|
|
public float preferredWidth { get { return minWidth; } }
|
|
/// <inheritdoc />
|
|
public float flexibleWidth { get { return -1; } }
|
|
|
|
/// <inheritdoc />
|
|
public float minHeight {
|
|
get {
|
|
return m_isVertical ? (transform as RectTransform).rect.width / m_aspectRatio : -1;
|
|
}
|
|
}
|
|
/// <inheritdoc />
|
|
public float preferredHeight { get { return minHeight; } }
|
|
/// <inheritdoc />
|
|
public float flexibleHeight { get { return -1; } }
|
|
|
|
/// <inheritdoc />
|
|
public int layoutPriority { get { return 1; } }
|
|
|
|
/// <inheritdoc />
|
|
public void CalculateLayoutInputHorizontal() { }
|
|
|
|
/// <inheritdoc />
|
|
public void CalculateLayoutInputVertical() { }
|
|
|
|
protected override void OnEnable() {
|
|
base.OnEnable();
|
|
SetDirty();
|
|
}
|
|
protected override void OnBeforeTransformParentChanged() {
|
|
base.OnBeforeTransformParentChanged();
|
|
SetDirty();
|
|
}
|
|
protected override void OnTransformParentChanged() {
|
|
base.OnTransformParentChanged();
|
|
SetDirty();
|
|
}
|
|
protected override void OnDidApplyAnimationProperties() {
|
|
base.OnDidApplyAnimationProperties();
|
|
SetDirty();
|
|
}
|
|
#if UNITY_EDITOR
|
|
protected override void OnValidate() {
|
|
base.OnValidate();
|
|
SetDirty();
|
|
}
|
|
#endif
|
|
protected override void OnDisable() {
|
|
SetDirty();
|
|
base.OnDisable();
|
|
}
|
|
protected override void OnRectTransformDimensionsChange() {
|
|
base.OnRectTransformDimensionsChange();
|
|
SetDirty();
|
|
}
|
|
bool _delayedSetDirty;
|
|
private void SetDirty() {
|
|
if (!IsActive()) return;
|
|
if (CanvasUpdateRegistry.IsRebuildingLayout()) _delayedSetDirty = true;
|
|
else LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
|
}
|
|
void Update() {
|
|
if (!_delayedSetDirty) return;
|
|
_delayedSetDirty = false;
|
|
LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
|
}
|
|
}
|
|
}
|