| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- namespace TheraBytes.BetterUi
- {
- [HelpURL("https://documentation.therabytes.de/better-ui/SizeChangeTracker.html")]
- [AddComponentMenu("Better UI/Helpers/Size Change Tracker", 30)]
- [RequireComponent(typeof(RectTransform))]
- [RequireComponent(typeof(ILayoutElement))]
- public class SizeChangeTracker : UIBehaviour, ILayoutSelfController
- {
- [Flags]
- public enum Axis
- {
- None = 0,
- Horizontal = 1 << 0,
- Vertical = 1 << 1,
- HorizontalAndVertical = Horizontal | Vertical,
- }
- public enum TrackMode
- {
- PreferredSize,
- MinSize,
- }
- public TrackMode SizeMode = TrackMode.PreferredSize;
- public Axis AffectedAxis = Axis.HorizontalAndVertical;
- public RectTransform[] AffectedObjects;
- bool isInRecursion = false;
- Vector2 previousSize;
- RectTransform rectTransform;
- public RectTransform RectTransform
- {
- get
- {
- if (rectTransform == null)
- {
- rectTransform = transform as RectTransform;
- }
- return rectTransform;
- }
- }
- protected override void OnEnable()
- {
- base.OnEnable();
- CallForAffectedObjects((dp) => dp.ChildAddedOrEnabled(this.transform), force: true);
- }
- protected override void OnDisable()
- {
- base.OnDisable();
- CallForAffectedObjects((dp) => dp.ChildRemovedOrDisabled(this.transform), force: true);
- previousSize = Vector2.zero;
- }
- protected override void OnTransformParentChanged()
- {
- base.OnTransformParentChanged();
- CallForAffectedObjects((dp) => dp.ChildRemovedOrDisabled(this.transform), force: true);
- previousSize = Vector2.zero;
- }
- protected override void OnRectTransformDimensionsChange()
- {
- base.OnRectTransformDimensionsChange();
- CallForAffectedObjects((dp) => dp.ChildSizeChanged(this.transform));
- }
- void ILayoutController.SetLayoutHorizontal()
- {
- if (!AffectedAxis.HasFlag(Axis.Horizontal))
- return;
- CallForAffectedObjects((dp) => dp.ChildSizeChanged(this.transform));
- }
- void ILayoutController.SetLayoutVertical()
- {
- if (!AffectedAxis.HasFlag(Axis.Vertical))
- return;
- CallForAffectedObjects((dp) => dp.ChildSizeChanged(this.transform));
- }
- private void CallForAffectedObjects(Action<ILayoutChildDependency> function, bool force = false)
- {
- if (function == null)
- throw new ArgumentNullException("function must not be null");
- if (isInRecursion)
- return;
- Vector2 size = GetCurrentSize();
- if (!force && !HasSizeChanged(size, previousSize))
- return;
- previousSize = size;
- isInRecursion = true;
- try
- {
- foreach (RectTransform rt in AffectedObjects)
- {
- if (rt == null)
- continue;
- foreach (ILayoutChildDependency dp in rt.GetComponents<ILayoutChildDependency>())
- {
- if (dp == null)
- continue;
- function(dp);
- }
- }
- }
- catch (Exception ex)
- {
- Debug.LogException(ex);
- }
- finally
- {
- isInRecursion = false;
- }
- }
- private Vector2 GetCurrentSize()
- {
- switch (SizeMode)
- {
- case TrackMode.PreferredSize:
- return new Vector2(
- LayoutUtility.GetPreferredWidth(RectTransform),
- LayoutUtility.GetPreferredHeight(RectTransform));
- case TrackMode.MinSize:
- return new Vector2(
- LayoutUtility.GetMinWidth(RectTransform),
- LayoutUtility.GetMinHeight(RectTransform));
- default: throw new ArgumentException();
- }
- }
- private bool HasSizeChanged(Vector2 size, Vector2 previousSize)
- {
- switch (AffectedAxis)
- {
- case Axis.None: return false;
- case Axis.Horizontal: return size.x != previousSize.x;
- case Axis.Vertical: return size.y != previousSize.y;
- case Axis.HorizontalAndVertical: return size != previousSize;
- default: throw new ArgumentException();
- }
- }
- }
- }
|