namespace SRF.UI { using Internal; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; [ExecuteInEditMode] [AddComponentMenu(ComponentMenuPaths.StyleComponent)] public class StyleComponent : SRMonoBehaviour { private Style _activeStyle; private StyleRoot _cachedRoot; private Graphic _graphic; private bool _hasStarted; private Image _image; private Selectable _selectable; [SerializeField] [FormerlySerializedAs("StyleKey")] [HideInInspector] private string _styleKey; public bool IgnoreImage = false; public string StyleKey { get { return _styleKey; } set { _styleKey = value; Refresh(false); } } private void Start() { Refresh(true); _hasStarted = true; } private void OnEnable() { if (_hasStarted) { Refresh(false); } } #if UNITY_EDITOR /// /// This method is not included in exported builds - don't worry about it showing up in the profiler. /// private void Update() { if (!Application.isPlaying) { ApplyStyle(); } } #endif public void Refresh(bool invalidateCache) { if (string.IsNullOrEmpty(StyleKey)) { _activeStyle = null; return; } if (!isActiveAndEnabled) { _cachedRoot = null; return; } if (_cachedRoot == null || invalidateCache) { _cachedRoot = GetStyleRoot(); } if (_cachedRoot == null) { Debug.LogWarning("[StyleComponent] No active StyleRoot object found in parents.", this); _activeStyle = null; return; } var s = _cachedRoot.GetStyle(StyleKey); if (s == null) { Debug.LogWarning("[StyleComponent] Style not found ({0})".Fmt(StyleKey), this); _activeStyle = null; return; } _activeStyle = s; ApplyStyle(); } /// /// Find the nearest enable style root component in parents /// /// private StyleRoot GetStyleRoot() { var t = CachedTransform; StyleRoot root; var i = 0; do { root = t.GetComponentInParent(); if (root != null) { t = root.transform.parent; } ++i; if (i > 100) { Debug.LogWarning("Breaking Loop"); break; } } while ((root != null && !root.enabled) && t != null); return root; } private void ApplyStyle() { if (_activeStyle == null) { return; } if (_graphic == null) { _graphic = GetComponent(); } if (_selectable == null) { _selectable = GetComponent(); } if (_image == null) { _image = GetComponent(); } if (!IgnoreImage && _image != null) { _image.sprite = _activeStyle.Image; } if (_selectable != null) { var colours = _selectable.colors; colours.normalColor = _activeStyle.NormalColor; colours.highlightedColor = _activeStyle.HoverColor; colours.pressedColor = _activeStyle.ActiveColor; colours.disabledColor = _activeStyle.DisabledColor; colours.colorMultiplier = 1f; _selectable.colors = colours; if (_graphic != null) { _graphic.color = Color.white; } } else if (_graphic != null) { _graphic.color = _activeStyle.NormalColor; } } private void SRStyleDirty() { // If inactive, invalidate the cached root and return. Next time it is enabled // a new root will be found if (!CachedGameObject.activeInHierarchy) { _cachedRoot = null; return; } Refresh(true); } } }