// 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.Generic; using System.Linq; using Doozy.Editor.EditorUI.Components.Internal; using Doozy.Editor.EditorUI.ScriptableObjects.Colors; using Doozy.Runtime.Colors; using Doozy.Runtime.Common.Extensions; using Doozy.Runtime.Reactor.Internal; using Doozy.Runtime.UIElements.Extensions; using UnityEngine.UIElements; // ReSharper disable MemberCanBePrivate.Global namespace Doozy.Editor.EditorUI.Components { public class FluidToggleGroup : FluidToggle, IToggleGroup { public override void Reset() { base.Reset(); SetLabelText(string.Empty); } #region LabelType private ToggleLabelType m_LabelType; public ToggleLabelType labelType { get => m_LabelType; set { m_LabelType = value; leftLabel.SetStyleDisplay(labelType == ToggleLabelType.LeftLabel ? DisplayStyle.Flex : DisplayStyle.None); rightLabel.SetStyleDisplay(labelType == ToggleLabelType.RightLabel ? DisplayStyle.Flex : DisplayStyle.None); } } #endregion public TemplateContainer templateContainer { get; } public VisualElement layoutContainer { get; } public Image iconContainer { get; } public Label leftLabel { get; } public Label rightLabel { get; } public enum GroupValue { Off = 0, On = 1, MixedValues = 2 } public GroupValue currentGroupValue { get; private set; } private void UpdateGroupValue(bool animateChange) { if (allTogglesAreOn) { currentGroupValue = GroupValue.On; } else if (allTogglesAreOff) { currentGroupValue = GroupValue.Off; } else { currentGroupValue = GroupValue.MixedValues; } hasMixedValues = currentGroupValue == GroupValue.MixedValues; bool previousValue = isOn; bool newValue = anyTogglesOn; this.SetIsOn(anyTogglesOn, animateChange); // isOn = anyTogglesOn; ValueChanged(previousValue, newValue, animateChange); } public enum ControlMode { /// /// Only one Toggle can be ON at any given time /// Allows for all Toggles to be OFF /// OneToggleOn, /// /// Only one Toggle will to be ON at any given time /// One Toggle will be forced ON at all times /// OneToggleOnEnforced, /// /// At least one Toggle needs to be ON at any given time /// Allows for multiple Toggles to be ON /// One Toggle will be forced ON at all times /// AnyToggleOnEnforced, /// /// Toggle values are not enforced in any way /// Allows for all Toggles to be OFF /// Passive, } private const ControlMode DEFAULT_CONTROL_MODE = ControlMode.OneToggleOnEnforced; public ControlMode currentControlMode { get; private set; } public FluidToggleGroup SetControlMode(ControlMode controlMode, bool animateChange = false) { currentControlMode = controlMode; UpdateGroupValue(animateChange); return this; } public readonly List Toggles = new List(); public int numberOfToggles => Toggles?.Count ?? 0; public int numberOfTogglesOn => Toggles?.Count(toggle => toggle.isOn) ?? 0; public int numberOfTogglesOff => Toggles?.Count(toggle => !toggle.isOn) ?? 0; public bool anyTogglesOn => Toggles?.Any(toggle => toggle.isOn) ?? false; public bool anyTogglesOff => Toggles?.Any(toggle => !toggle.isOn) ?? false; public bool allTogglesAreOn => Toggles?.All(toggle => toggle.isOn) ?? false; public bool allTogglesAreOff => Toggles?.All(toggle => !toggle.isOn) ?? false; public List togglesOn => Toggles?.Where(toggle => toggle.isOn).ToList(); public IToggle firstToggleOn => Toggles?.First(toggle => toggle.isOn); public int firstToggleOnIndex { get { if (Toggles == null) return -1; for (int index = 0; index < Toggles.Count; index++) { IToggle toggle = Toggles[index]; if (toggle.isOn) return index; } return -1; } } public IToggle lastToggleOn => Toggles?.Last(toggle => toggle.isOn); public int lastToggleOnIndex { get { if (Toggles == null) return -1; for (int index = Toggles.Count - 1; index >= 0; index--) { IToggle toggle = Toggles[index]; if (toggle.isOn) return index; } return -1; } } public List togglesOff => Toggles?.Where(toggle => !toggle.isOn).ToList(); public IToggle firstToggleOff => Toggles?.First(toggle => !toggle.isOn); public int firstToggleOffIndex { get { if (Toggles == null) return -1; for (int index = 0; index < Toggles.Count; index++) { IToggle toggle = Toggles[index]; if (!toggle.isOn) return index; } return -1; } } public IToggle lastToggleOff => Toggles?.Last(toggle => !toggle.isOn); public int lastToggleOffIndex { get { if (Toggles == null) return -1; for (int index = Toggles.Count - 1; index >= 0; index--) { IToggle toggle = Toggles[index]; if (!toggle.isOn) return index; } return -1; } } public static FluidToggleGroup Get(string labelText, bool value, EditorSelectableColorInfo accentColor, string tooltip = "") => Get().SetLabelText(labelText).SetToggleAccentColor(accentColor).SetIsOn(value).SetTooltip(tooltip); public static FluidToggleGroup Get(string labelText) => Get(labelText, false, null, string.Empty); public static FluidToggleGroup Get(bool value, EditorSelectableColorInfo accentColor = null, string tooltip = "") => Get(string.Empty, value, accentColor, tooltip); public static FluidToggleGroup Get(EditorSelectableColorInfo accentColor, string tooltip = "") => Get(string.Empty, false, accentColor, tooltip); public FluidToggleGroup() { Add(templateContainer = EditorLayouts.EditorUI.FluidToggle.CloneTree()); templateContainer .AddStyle(EditorStyles.EditorUI.LayoutContainer) .AddStyle(EditorStyles.EditorUI.FieldName) .AddStyle(EditorStyles.EditorUI.FluidToggle); layoutContainer = templateContainer.Q(nameof(layoutContainer)); iconContainer = layoutContainer.Q(nameof(iconContainer)); icon = iconContainer.Q(nameof(icon)); leftLabel = layoutContainer.Q