// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Animancer.Editor
{
/// [Editor-Only] A custom GUI for .
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/ParameterGUI_1
///
[CustomGUI(typeof(IParameter))]
public class ParameterGUI : CustomGUI
where TParameter : IParameter
{
/************************************************************************************************************************/
private static readonly HashSet
ExpandedNames = new();
/************************************************************************************************************************/
private static ICustomGUI _ValueGUI;
private static ICustomGUI _DelegateGUI;
/************************************************************************************************************************/
///
public override void DoGUI()
{
ParameterDictionary.IsDrawingInspector = true;
var isExpanded = DoFoldoutGUI(out var startArea);
DoValueGUI();
if (isExpanded)
{
EditorGUI.indentLevel++;
DoDetailsGUI();
EditorGUI.indentLevel--;
}
ParameterDictionary.IsDrawingInspector = false;
var endArea = GUILayoutUtility.GetLastRect();
var totalArea = startArea;
totalArea.yMax = endArea.yMax;
if (AnimancerGUI.TryUseClickEvent(totalArea, 1))
ShowContextMenu();
}
/************************************************************************************************************************/
/// Draws the and returns the area used.
private Rect DoValueGUI()
{
_ValueGUI ??= CustomGUIFactory.GetOrCreateForType(Value.ValueType);
_ValueGUI.Label = Label;
_ValueGUI.Value = Value.Value;
_ValueGUI.DoGUI();
Value.Value = _ValueGUI.Value;
return GUILayoutUtility.GetLastRect();
}
/************************************************************************************************************************/
/// Draws a foldout for the parameter details and returns true if expanded.
private bool DoFoldoutGUI(out Rect totalArea)
{
var area = AnimancerGUI.LayoutSingleLineRect();
totalArea = area;
GUILayout.Space(-AnimancerGUI.LineHeight - AnimancerGUI.StandardSpacing);
var indented = EditorGUI.IndentedRect(area);
area.xMax = indented.xMin;
EditorGUIUtility.AddCursorRect(area, MouseCursor.Arrow);
return AnimancerGUI.DoHashedFoldoutGUI(area, ExpandedNames, Label.text);
}
/************************************************************************************************************************/
/// Draws the details of the parameter.
private void DoDetailsGUI()
{
EditorGUILayout.LabelField("Type", Value.ValueType.GetNameCS(false));
_DelegateGUI ??= CustomGUIFactory.GetOrCreateForType(typeof(MulticastDelegate));
_DelegateGUI.SetLabel("On Value Changed");
_DelegateGUI.Value = Value.GetOnValueChanged();
_DelegateGUI.DoGUI();
}
/************************************************************************************************************************/
/// Shows a context menu for the parameter.
private void ShowContextMenu()
{
var menu = new GenericMenu();
menu.AddItem(new("Log Interactions"), Value.LogContext != null, () =>
{
Value.LogContext = Value.LogContext is null
? ""
: null;
});
menu.AddItem(new("Inspector Control Only"), Value.InspectorControlOnly, () =>
{
Value.InspectorControlOnly = !Value.InspectorControlOnly;
});
AnimancerEditorUtilities.AddDocumentationLink(
menu,
"Parameters Documentation",
Strings.DocsURLs.Parameters);
menu.ShowAsContext();
}
/************************************************************************************************************************/
}
}
#endif