using Cryville.Common; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Cryville.Crtr.Browsing.UI { [ExecuteAlways] internal class BrowserTabLayout : UIBehaviour, ILayoutElement { [SerializeField] float m_minWidth = 150; public float MinWidth { get { return m_minWidth; } set { if (m_minWidth == value) return; m_minWidth = value; UpdateTweener(); } } float GetTargetLayoutMinWidth() { var width = MinWidth; if (Selected) { var preferredWidth = LayoutUtility.GetPreferredWidth(transform as RectTransform); if (preferredWidth > width) width = preferredWidth; } return width; } float m_layoutMinWidth = -1; float ILayoutElement.minWidth { get { return m_layoutMinWidth; } } void UpdateLayoutMinWidth(float value) { if (m_layoutMinWidth == value) return; m_layoutMinWidth = value; SetDirty(); } public float preferredWidth { get { return -1; } } public float flexibleWidth { get { return -1; } } public float minHeight { get { return -1; } } public float preferredHeight { get { return -1; } } public float flexibleHeight { get { return -1; } } public int layoutPriority { get { return 1; } } bool m_selected; public bool Selected { get { return m_selected; } set { if (m_selected == value) return; m_selected = value; UpdateTweener(); } } [SerializeField] float m_tweenDuration = 0.2f; float _lastWidth; bool _delayedUpdate; PropertyTweener _tweener; void UpdateTweener() { var width = GetTargetLayoutMinWidth(); _tweener.Start(width, m_tweenDuration); if (width != _lastWidth) { _lastWidth = width; _delayedUpdate = true; } } void Update() { if (_delayedUpdate) { _delayedUpdate = false; UpdateTweener(); } _tweener.Advance(Time.deltaTime); } public void CalculateLayoutInputHorizontal() { } public void CalculateLayoutInputVertical() { } protected override void OnEnable() { base.OnEnable(); m_layoutMinWidth = GetTargetLayoutMinWidth(); _tweener ??= new PropertyTweener( () => m_layoutMinWidth, v => UpdateLayoutMinWidth(v), Tweeners.Float.With(EasingFunctions.OutQuad) ); 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(); } void SetDirty() { if (!IsActive()) return; LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform); } } }