275 lines
14 KiB
C#
275 lines
14 KiB
C#
// 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 Doozy.Editor.Common.Extensions;
|
|
using Doozy.Editor.EditorUI;
|
|
using Doozy.Editor.EditorUI.Components;
|
|
using Doozy.Editor.EditorUI.Components.Internal;
|
|
using Doozy.Editor.EditorUI.ScriptableObjects.Colors;
|
|
using Doozy.Editor.EditorUI.Utils;
|
|
using Doozy.Editor.UIElements;
|
|
using Doozy.Runtime.Reactor;
|
|
using Doozy.Runtime.Reactor.Animations;
|
|
using Doozy.Runtime.UIElements.Extensions;
|
|
using UnityEditor;
|
|
using UnityEditor.UIElements;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace Doozy.Editor.Reactor.Drawers
|
|
{
|
|
[CustomPropertyDrawer(typeof(FloatAnimation), true)]
|
|
public class FloatAnimationDrawer : PropertyDrawer
|
|
{
|
|
private static Color accentColor => EditorColors.Reactor.Red;
|
|
private static EditorSelectableColorInfo selectableAccentColor => EditorSelectableColors.Reactor.Red;
|
|
|
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
|
{
|
|
var drawer = new VisualElement();
|
|
if (property == null) return drawer;
|
|
drawer.RegisterCallback<DetachFromPanelEvent>(evt => drawer.RecycleAndClear());
|
|
var target = property.GetTargetObjectOfProperty() as FloatAnimation;
|
|
|
|
#region SerializedProperties
|
|
|
|
//Animation
|
|
SerializedProperty propertyAnimation = property.FindPropertyRelative("Animation");
|
|
SerializedProperty propertyAnimationEnabled = propertyAnimation.FindPropertyRelative("Enabled");
|
|
//Callbacks
|
|
SerializedProperty propertyOnPlayCallback = property.FindPropertyRelative("OnPlayCallback");
|
|
SerializedProperty propertyOnStopCallback = property.FindPropertyRelative("OnStopCallback");
|
|
SerializedProperty propertyOnFinishCallback = property.FindPropertyRelative("OnFinishCallback");
|
|
|
|
#endregion
|
|
|
|
#region ComponentHeader
|
|
|
|
FluidComponentHeader componentHeader =
|
|
FluidComponentHeader.Get()
|
|
.SetAccentColor(accentColor)
|
|
.SetElementSize(ElementSize.Tiny)
|
|
.SetComponentNameText("Reflected Float")
|
|
.SetComponentTypeText("Animation")
|
|
.AddManualButton()
|
|
.AddApiButton()
|
|
.AddYouTubeButton();
|
|
|
|
#endregion
|
|
|
|
#region Containers
|
|
|
|
VisualElement contentContainer = new VisualElement().SetName("Content Container").SetStyleFlexGrow(1);
|
|
FluidAnimatedContainer settingsAnimatedContainer = new FluidAnimatedContainer("Animation", true).Hide(false);
|
|
FluidAnimatedContainer callbacksAnimatedContainer = new FluidAnimatedContainer("Callbacks", true).Hide(false);
|
|
|
|
//settings container content
|
|
settingsAnimatedContainer.SetOnShowCallback(() =>
|
|
{
|
|
settingsAnimatedContainer
|
|
.AddContent(GetAnimationContent(propertyAnimation, propertyAnimationEnabled))
|
|
.Bind(property.serializedObject);
|
|
});
|
|
|
|
//callbacks container content
|
|
callbacksAnimatedContainer.SetOnShowCallback(() =>
|
|
{
|
|
callbacksAnimatedContainer
|
|
.AddContent
|
|
(
|
|
FluidField.Get()
|
|
.AddFieldContent(DesignUtils.NewPropertyField(propertyOnPlayCallback.propertyPath))
|
|
.AddFieldContent(DesignUtils.spaceBlock)
|
|
.AddFieldContent(DesignUtils.NewPropertyField(propertyOnStopCallback.propertyPath))
|
|
.AddFieldContent(DesignUtils.spaceBlock)
|
|
.AddFieldContent(DesignUtils.NewPropertyField(propertyOnFinishCallback.propertyPath))
|
|
)
|
|
.AddContent(DesignUtils.endOfLineBlock)
|
|
.Bind(property.serializedObject);
|
|
});
|
|
|
|
#endregion
|
|
|
|
#region Toolbar
|
|
|
|
VisualElement toolbarContainer =
|
|
new VisualElement()
|
|
.SetName("Toolbar Container")
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.SetStyleMarginTop(-1)
|
|
.SetStyleMarginLeft(4)
|
|
.SetStyleMarginRight(4)
|
|
.SetStyleFlexGrow(1);
|
|
|
|
FluidTab settingsTab =
|
|
FluidTab.Get()
|
|
.SetLabelText("Settings")
|
|
.SetElementSize(ElementSize.Small)
|
|
.SetIcon(EditorSpriteSheets.EditorUI.Icons.Settings)
|
|
.ButtonSetAccentColor(selectableAccentColor)
|
|
.IndicatorSetEnabledColor(accentColor)
|
|
.ButtonSetOnValueChanged(evt => settingsAnimatedContainer.Toggle(evt.newValue));
|
|
|
|
FluidTab callbacksTab =
|
|
FluidTab.Get()
|
|
.SetLabelText("Callbacks")
|
|
.SetElementSize(ElementSize.Small)
|
|
.SetIcon(EditorSpriteSheets.EditorUI.Icons.UnityEvent)
|
|
.ButtonSetAccentColor(DesignUtils.callbackSelectableColor)
|
|
.IndicatorSetEnabledColor(DesignUtils.callbacksColor)
|
|
.ButtonSetOnValueChanged(evt => callbacksAnimatedContainer.Toggle(evt.newValue));
|
|
|
|
//create tabs group
|
|
FluidToggleGroup tabsGroup = FluidToggleGroup.Get().SetControlMode(FluidToggleGroup.ControlMode.OneToggleOn);
|
|
settingsTab.button.AddToToggleGroup(tabsGroup);
|
|
callbacksTab.button.AddToToggleGroup(tabsGroup);
|
|
|
|
//update tab indicators
|
|
drawer.schedule.Execute(() =>
|
|
{
|
|
void UpdateIndicator(FluidTab fluidTab, bool toggleOn, bool animateChange)
|
|
{
|
|
if (fluidTab.indicator.isOn == toggleOn) return;
|
|
fluidTab.indicator.Toggle(toggleOn, animateChange);
|
|
}
|
|
|
|
bool HasCallbacks() =>
|
|
target != null &&
|
|
target.OnPlayCallback?.GetPersistentEventCount() > 0 | //HasOnPlayCallback
|
|
target.OnStopCallback?.GetPersistentEventCount() > 0 | //HasOnPlayCallback
|
|
target.OnFinishCallback?.GetPersistentEventCount() > 0; //HasOnFinishCallback
|
|
|
|
//initial indicators state update (no animation)
|
|
UpdateIndicator(settingsTab, propertyAnimationEnabled.boolValue, false);
|
|
UpdateIndicator(callbacksTab, HasCallbacks(), false);
|
|
|
|
drawer.schedule.Execute(() =>
|
|
{
|
|
//subsequent indicators state update (animated)
|
|
UpdateIndicator(settingsTab, propertyAnimationEnabled.boolValue, true);
|
|
UpdateIndicator(callbacksTab, HasCallbacks(), true);
|
|
|
|
}).Every(200);
|
|
});
|
|
|
|
toolbarContainer
|
|
.AddChild(settingsTab)
|
|
.AddSpaceBlock()
|
|
.AddChild(callbacksTab)
|
|
.AddSpaceBlock()
|
|
.AddChild(DesignUtils.flexibleSpace);
|
|
|
|
#endregion
|
|
|
|
#region Compose
|
|
|
|
drawer
|
|
.AddChild(componentHeader)
|
|
.AddChild(toolbarContainer)
|
|
.AddSpaceBlock(2)
|
|
.AddChild
|
|
(
|
|
contentContainer
|
|
.AddChild(settingsAnimatedContainer)
|
|
.AddChild(callbacksAnimatedContainer)
|
|
);
|
|
|
|
#endregion
|
|
|
|
return drawer;
|
|
}
|
|
|
|
private static VisualElement GetAnimationContent(SerializedProperty propertyAnimation, SerializedProperty propertyAnimationEnabled)
|
|
{
|
|
SerializedProperty propertyFromReferenceValue = propertyAnimation.FindPropertyRelative("FromReferenceValue");
|
|
SerializedProperty propertyToReferenceValue = propertyAnimation.FindPropertyRelative("ToReferenceValue");
|
|
SerializedProperty propertyFromOffset = propertyAnimation.FindPropertyRelative("FromOffset");
|
|
SerializedProperty propertyToOffset = propertyAnimation.FindPropertyRelative("ToOffset");
|
|
SerializedProperty propertyFromCustomValue = propertyAnimation.FindPropertyRelative("FromCustomValue");
|
|
SerializedProperty propertyToCustomValue = propertyAnimation.FindPropertyRelative("ToCustomValue");
|
|
SerializedProperty propertySettings = propertyAnimation.FindPropertyRelative("Settings");
|
|
|
|
var content = new VisualElement();
|
|
content.SetEnabled(propertyAnimationEnabled.boolValue);
|
|
FluidToggleSwitch enableSwitch = DesignUtils.GetEnableDisableSwitch(propertyAnimationEnabled, content, selectableAccentColor, "Animation");
|
|
|
|
const int height = 42;
|
|
|
|
FluidField fromReferenceValueFluidField = FluidField.Get<EnumField>(propertyFromReferenceValue, "From Value").SetStyleHeight(height, height, height);
|
|
FluidField toReferenceValueFluidField = FluidField.Get<EnumField>(propertyToReferenceValue, "To Value").SetStyleHeight(height, height, height);
|
|
|
|
FluidField fromOffsetFluidField = FluidField.Get<FloatField>(propertyFromOffset, "From Offset").SetStyleHeight(height, height, height);
|
|
FluidField toOffsetFluidField = FluidField.Get<FloatField>(propertyToOffset, "To Offset").SetStyleHeight(height, height, height);
|
|
|
|
FluidField fromCustomValueFluidField = FluidField.Get<FloatField>(propertyFromCustomValue, "From Custom Value").SetStyleHeight(height, height, height);
|
|
FluidField toCustomValueFluidField = FluidField.Get<FloatField>(propertyToCustomValue, "To Custom Value").SetStyleHeight(height, height, height);
|
|
|
|
PropertyField settingsPropertyField = DesignUtils.NewPropertyField(propertySettings).SetName("Animation Settings");
|
|
|
|
VisualElement foldoutContent =
|
|
new VisualElement()
|
|
.AddChild
|
|
(
|
|
DesignUtils.row
|
|
.AddChild(enableSwitch)
|
|
.AddChild(DesignUtils.flexibleSpace)
|
|
)
|
|
.AddChild
|
|
(
|
|
content
|
|
.AddChild
|
|
(
|
|
DesignUtils.row
|
|
.SetName("From To Settings")
|
|
.AddChild
|
|
(
|
|
DesignUtils.column
|
|
.SetName("From Settings")
|
|
.AddChild(fromReferenceValueFluidField)
|
|
.AddSpaceBlock()
|
|
.AddChild(fromOffsetFluidField)
|
|
.AddChild(fromCustomValueFluidField)
|
|
)
|
|
.AddSpaceBlock()
|
|
.AddChild
|
|
(
|
|
DesignUtils.column
|
|
.SetName("To Settings")
|
|
.AddChild(toReferenceValueFluidField)
|
|
.AddSpaceBlock()
|
|
.AddChild(toOffsetFluidField)
|
|
.AddChild(toCustomValueFluidField)
|
|
)
|
|
)
|
|
.AddSpaceBlock()
|
|
.AddChild(settingsPropertyField)
|
|
.AddEndOfLineSpace()
|
|
);
|
|
|
|
void Update()
|
|
{
|
|
fromOffsetFluidField.SetStyleDisplay((ReferenceValue)propertyFromReferenceValue.enumValueIndex == ReferenceValue.CustomValue ? DisplayStyle.None : DisplayStyle.Flex);
|
|
fromCustomValueFluidField.SetStyleDisplay((ReferenceValue)propertyFromReferenceValue.enumValueIndex != ReferenceValue.CustomValue ? DisplayStyle.None : DisplayStyle.Flex);
|
|
toOffsetFluidField.SetStyleDisplay((ReferenceValue)propertyToReferenceValue.enumValueIndex == ReferenceValue.CustomValue ? DisplayStyle.None : DisplayStyle.Flex);
|
|
toCustomValueFluidField.SetStyleDisplay((ReferenceValue)propertyToReferenceValue.enumValueIndex != ReferenceValue.CustomValue ? DisplayStyle.None : DisplayStyle.Flex);
|
|
}
|
|
|
|
//FromReferenceValue
|
|
EnumField invisibleFieldRotateFromReferenceValueEnum = new EnumField { bindingPath = propertyFromReferenceValue.propertyPath }.SetStyleDisplay(DisplayStyle.None);
|
|
foldoutContent.AddChild(invisibleFieldRotateFromReferenceValueEnum);
|
|
invisibleFieldRotateFromReferenceValueEnum.RegisterValueChangedCallback(changeEvent => Update());
|
|
|
|
//ToReferenceValue
|
|
EnumField invisibleFieldRotateToReferenceValueEnum = new EnumField { bindingPath = propertyToReferenceValue.propertyPath }.SetStyleDisplay(DisplayStyle.None);
|
|
foldoutContent.AddChild(invisibleFieldRotateToReferenceValueEnum);
|
|
invisibleFieldRotateToReferenceValueEnum.RegisterValueChangedCallback(changeEvent => Update());
|
|
|
|
foldoutContent.Bind(propertyAnimation.serializedObject);
|
|
|
|
Update();
|
|
return foldoutContent;
|
|
}
|
|
}
|
|
}
|