using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace Amanotes.Core { partial class Widget2D // Size2D { [SerializeField] protected internal Size2D _size = new Size2D(); public Vector2 size { get => _size; set { if (_size == value) return; _size.SetSize(value); Refresh(); } } public Vector2 pivot { get => _size.pivot; set => _size.pivot = value; } /// When true, widget height maps to local Z (e.g. flat XZ tiles). public bool scrollAxisIsZ => _size.useZ; public float width { get => ((Vector2)_size).x; set { var v = size; if (Mathf.Approximately(v.x, value)) return; v.x = value; _size.SetSize(v); Refresh(); } } public float height { get => ((Vector2)_size).y; set { var v = size; if (Mathf.Approximately(v.y, value)) return; v.y = value; _size.SetSize(v); Refresh(); } } #if UNITY_EDITOR private void OnDrawGizmosSelected() { _size.DrawGizmoSelected(transform); DrawComputedRectGizmos(); } private void OnDrawGizmos() => _size.DrawGizmo(transform); #endif } partial class Widget2D // Legacy (kept for serialization compat) { [HideInInspector] [SerializeField] private List targets; protected void RefreshComponentsOnly() { ComputeAllRects(); ApplyTargets2(); } } partial class Widget2D // Listeners { [HideInInspector] [SerializeField] private List listeners = new List(); // Runtime-only rectId bindings for listeners (not serialized — set from code) [System.NonSerialized] private Dictionary _listenerRectBindings; private void NotifyListeners() { if (this == null || listeners == null) return; for (var i = listeners.Count - 1; i >= 0; i--) { var lsn = listeners[i]; if (lsn == null) continue; if (!(lsn is ISizeListener handler)) continue; // Check if listener has a rect binding if (_listenerRectBindings != null && _listenerRectBindings.TryGetValue(lsn, out var rectId) && !string.IsNullOrEmpty(rectId)) { handler.OnResize(GetRectSize(rectId)); } else { handler.OnResize(_size); } } } internal bool AddListener(Component c) { if (c == null) return false; if (listeners.Contains(c)) return true; if (!(c is ISizeListener)) return false; listeners.Add(c); return true; } /// /// Add a listener bound to a specific derived rect ID. /// The listener's OnResize will receive the derived rect's size instead of raw widget size. /// internal bool AddListener(Component c, string rectId) { if (!AddListener(c)) return false; if (!string.IsNullOrEmpty(rectId)) { _listenerRectBindings ??= new Dictionary(4); _listenerRectBindings[c] = rectId; } return true; } internal bool RemoveListener(Component c) { if (c == null || listeners == null) return false; _listenerRectBindings?.Remove(c); return listeners.Remove(c); } internal bool ContainsListener(Component c) { return listeners != null && listeners.Contains(c); } #if UNITY_EDITOR internal void Scan4Listeners(GameObject go) { var monos = go.GetComponents(); for (var i = 0; i < monos.Length; i++) { AddListener(monos[i]); } } #endif } public partial class Widget2D : MonoBehaviour { #if UNITY_EDITOR private void OnValidate() { if (PrefabUtility.IsPartOfPrefabAsset(gameObject)) return; #pragma warning disable UDR0005 EditorApplication.delayCall += Refresh; #pragma warning restore UDR0005 } #endif public virtual void Refresh() { ComputeAllRects(); ApplyTargets2(); NotifyListeners(); } } }