// 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.Collections.Generic; using Doozy.Editor.EditorUI.Utils; using Doozy.Editor.Reactor.Internal; using Doozy.Editor.UIElements; using Doozy.Runtime.Common.Extensions; using Doozy.Runtime.Reactor.Extensions; using Doozy.Runtime.Reactor.Internal; using Doozy.Runtime.Reactor.Reactions; using Doozy.Runtime.UIElements; using Doozy.Runtime.UIElements.Extensions; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace Doozy.Editor.EditorUI.Components { public class FluidField : PoolableElement { public sealed override void Reset() { templateContainer.SetStyleFlexGrow(1); this.ResetLayout(); this.SetTooltip(string.Empty); this.SetStyleFlexGrow(1); this.SetStyleFlexShrink(1); this.SetStyleFlexBasisStyleLength(new StyleLength(StyleKeyword.Auto)); this.SetEnabled(true); fieldContainer.SetStyleFlexGrow(1); fieldContent.SetStyleFlexGrow(1); DisableIconAnimation(false); ResetElementSize(); ClearLabelText(); fieldLabel.SetStyleWidth(StyleKeyword.Auto); ClearIcon(); ClearFieldContent(); fieldContent.ResetLayout(); ClearInfoContainer(); ResetBackground(); LayoutContainerRestoreLayout(); } public override void Dispose() { base.Dispose(); iconReaction?.Recycle(); } public const float k_IconReactionDuration = 1f; #region ElementSize private ElementSize elementSize { get; set; } private List elementSizeDependentElements { get; } public FluidField SetElementSize(ElementSize value) { UIElementsUtils.RemoveClass(elementSize.ToString(), elementSizeDependentElements); UIElementsUtils.AddClass(value.ToString(), elementSizeDependentElements); elementSize = value; return this; } public FluidField ResetElementSize() => SetElementSize(ElementSize.Small); #endregion #region IconType private IconType iconType { get; set; } = IconType.None; private List iconDependentComponents { get; } private void UpdateIconType(IconType value) { if (iconType != IconType.None) UIElementsUtils.RemoveClass(iconType.ToString(), iconDependentComponents); if (value != IconType.None) UIElementsUtils.AddClass(value.ToString(), iconDependentComponents); iconType = value; } #endregion public TemplateContainer templateContainer { get; } public VisualElement layoutContainer { get; } public VisualElement iconContainer { get; } public Image fieldIcon { get; } public VisualElement fieldContainer { get; } public Label fieldLabel { get; } public VisualElement fieldContent { get; } public VisualElement infoContainer { get; } public Texture2DReaction iconReaction { get; private set; } public bool disableIconAnimation { get; private set; } public static FluidField Get(string fieldName) => Get().SetLabelText(fieldName); public static FluidField Get(VisualElement content) => Get().AddFieldContent(content); public static FluidField Get(string fieldName, VisualElement content) => Get().SetLabelText(fieldName).AddFieldContent(content); public static FluidField Get(SerializedProperty property, string labelText = "", string tooltip = "", bool tryToRemovePropertyLabel = false) where T : VisualElement, IBindable, new() => Get(property.propertyPath, labelText, tooltip, tryToRemovePropertyLabel); public static FluidField Get(string bindingPath, string labelText = "", string tooltip = "", bool tryToRemovePropertyLabel = false) where T : VisualElement, IBindable, new() { T bindable = new T { bindingPath = bindingPath } .ResetLayout() .SetName($"{typeof(T).Name}: {bindingPath}") .SetTooltip(tooltip); if (tryToRemovePropertyLabel) bindable.TryToHideLabel(); return Get().SetLabelText(labelText, tooltip).AddFieldContent(bindable); } public static FluidField Get(T fieldContentElement, string labelText = "", string tooltip = "") where T : VisualElement => Get().SetLabelText(labelText, tooltip).AddFieldContent(fieldContentElement); /// /// Do not use this as new FluidField() as that option does not use the internal pooling system /// use: 'FluidField.Get()' to get a new instance (this uses the internal pooling system) /// public FluidField() { this.SetStyleFlexGrow(1); Add(templateContainer = EditorLayouts.EditorUI.FluidField.CloneTree()); templateContainer .SetStyleFlexGrow(1) .AddStyle(EditorStyles.EditorUI.FluidField); layoutContainer = templateContainer.Q(nameof(layoutContainer)); iconContainer = layoutContainer.Q(nameof(iconContainer)); fieldIcon = iconContainer.Q(nameof(fieldIcon)); fieldContainer = layoutContainer.Q(nameof(fieldContainer)); fieldLabel = fieldContainer.Q