2025-05-09 15:40:34 +08:00

127 lines
4.2 KiB
C#

// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using static Animancer.Editor.AnimancerGUI;
namespace Animancer.Editor
{
/// <summary>[Editor-Only] Utility for a toggle which can show and hide a speed slider.</summary>
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/ToggledSpeedSlider
public class ToggledSpeedSlider
{
/************************************************************************************************************************/
/// <summary>The content displayed on the toggle.</summary>
/// <remarks>The <see cref="GUIContent.text"/> is set by the <see cref="Speed"/>.</remarks>
public readonly GUIContent GUIContent = new();
/// <summary>Is the toggle currently on?</summary>
public readonly BoolPref IsOn;
/************************************************************************************************************************/
private float _Speed = float.NaN;
/// <summary>The current speed value.</summary>
public float Speed
{
get => _Speed;
set
{
if (_Speed == value)
return;
_Speed = value;
GUIContent.text = _Speed.ToString("0.0x");
OnSetSpeed(_Speed);
}
}
/// <summary>Called when the <see cref="Speed"/> is changed.</summary>
protected virtual void OnSetSpeed(float speed) { }
/************************************************************************************************************************/
/// <summary>Creates a new <see cref="ToggledSpeedSlider"/>.</summary>
public ToggledSpeedSlider(string prefKey)
{
IsOn = new(prefKey);
}
/************************************************************************************************************************/
/// <summary>Draws a toggle to show or hide the speed slider.</summary>
public virtual bool DoToggleGUI(Rect area, GUIStyle style)
{
HandleResetClick(area);
style ??= GUI.skin.toggle;
IsOn.Value = GUI.Toggle(area, IsOn, GUIContent, style);
return IsOn;
}
/************************************************************************************************************************/
private static float _SpeedLabelWidth;
/// <summary>Draws a slider to control the <see cref="Speed"/>.</summary>
public float DoSpeedSlider(ref Rect area, GUIStyle backgroundStyle = null)
{
if (!IsOn)
return Speed;
var sliderArea = StealLineFromTop(ref area);
sliderArea = sliderArea.Expand(-StandardSpacing, 0);
if (backgroundStyle != null)
GUI.Label(sliderArea, GUIContent.none, backgroundStyle);
HandleResetClick(sliderArea);
var label = "Speed";
if (_SpeedLabelWidth == 0)
_SpeedLabelWidth = CalculateLabelWidth(label);
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = _SpeedLabelWidth;
EditorGUI.BeginChangeCheck();
var speed = EditorGUI.Slider(sliderArea, label, Speed, 0.1f, 2);
if (EditorGUI.EndChangeCheck())
Speed = speed;
EditorGUIUtility.labelWidth = labelWidth;
return Speed;
}
/************************************************************************************************************************/
/// <summary>Handles Right or Middle Clicking in the `area` to reset the <see cref="Speed"/>.</summary>
public void HandleResetClick(Rect area)
{
if (!TryUseClickEvent(area, 1) && !TryUseClickEvent(area, 2))
return;
if (Speed != 1)
Speed = 1;
else
Speed = 0.5f;
}
/************************************************************************************************************************/
}
}
#endif