// 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