// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using System; using System.Collections; using Doozy.Runtime.Common.Utils; using Doozy.Runtime.UIManager.Containers; using UnityEngine; // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Local namespace Doozy.Runtime.UIManager.Components { /// /// Toggle component, based on UIToggle, that can sync its state with a UIContainer. /// [RequireComponent(typeof(RectTransform))] [AddComponentMenu("Doozy/UI/Components/UITab")] [SelectionBase] public partial class UITab : UIToggle { #if UNITY_EDITOR [UnityEditor.MenuItem("GameObject/Doozy/UI/Components/UITab", false, 8)] private static void CreateComponent(UnityEditor.MenuCommand menuCommand) { GameObjectUtils.AddToScene("UITab", false, true); } #endif [SerializeField] private UIContainer TargetContainer; /// Reference to the target container controlled by this UITab public UIContainer targetContainer { get => TargetContainer; set { if (TargetContainer == value) return; DisconnectFromContainer(); TargetContainer = value; ConnectToContainer(true); } } /// /// Internal flag used to keep track if the UITab is currently connected to a container /// private bool isConnectedToContainer { get; set; } /// Connects the UITab to the referenced target container /// If TRUE, the UITab will update its isOn value to match the target container's isOn value private void ConnectToContainer(bool updateIsOn) { // Debug.Log($"[UITab] ConnectToContainer - updateIsOn: {updateIsOn}"); if (TargetContainer == null) { isConnectedToContainer = false; return; } if (isConnectedToContainer) return; TargetContainer.OnShowCallback.Event.AddListener(UpdateIsOnFromContainer); TargetContainer.OnHideCallback.Event.AddListener(UpdateIsOnFromContainer); if (updateIsOn) UpdateIsOnFromContainer(); isConnectedToContainer = true; // Debug.Log($"[UITab] '{name}' Connected to container '{TargetContainer.name}'"); } /// Disconnects the UITab from the referenced target container private void DisconnectFromContainer() { if (TargetContainer == null) return; TargetContainer.OnShowCallback.Event.RemoveListener(UpdateIsOnFromContainer); TargetContainer.OnHideCallback.Event.RemoveListener(UpdateIsOnFromContainer); // Debug.Log($"[UITab] '{name}' Disconnected from container '{TargetContainer.name}'"); TargetContainer = null; isOn = false; isConnectedToContainer = false; } /// Updates the UITab's isOn value to match the target container's isOn value /// private void UpdateIsOnFromContainer() { // Debug.Log($"[UITab] '{name}' UpdateIsOnFromContainer {TargetContainer.visibilityState} --> isOn = {isOn}"); switch (TargetContainer.visibilityState) { case VisibilityState.Visible: case VisibilityState.IsShowing: if (isOn) break; isOn = true; break; case VisibilityState.Hidden: case VisibilityState.IsHiding: if(!isOn) break; isOn = false; break; default: throw new ArgumentOutOfRangeException(); } } protected override void Awake() { isConnectedToContainer = false; base.Awake(); ConnectToContainer(false); } protected override void OnEnable() { base.OnEnable(); StartCoroutine($"UpdateConnection"); } internal override void ValueChanged(bool previousValue, bool newValue, bool animateChange, bool triggerValueChanged) { base.ValueChanged(previousValue, newValue, animateChange, triggerValueChanged); if (!isConnectedToContainer) return; switch (isOn) { case true: if (animateChange) { TargetContainer.Show(); break; } TargetContainer.InstantShow(); break; case false: if (animateChange) { TargetContainer.Hide(); break; } TargetContainer.InstantHide(); break; } } private IEnumerable UpdateConnection() { yield return null; ConnectToContainer(false); if (inToggleGroup) { ValueChanged(isOn, isConnectedToContainer && isOn, false, false); yield break; } UpdateIsOnFromContainer(); } } }