chore: initial commit
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2026 Kybernetik //
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using Animancer.TransitionLibraries;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using static Animancer.Editor.AnimancerGUI;
|
||||
using static Animancer.Editor.TransitionLibraries.TransitionLibrarySelection;
|
||||
|
||||
namespace Animancer.Editor.TransitionLibraries
|
||||
{
|
||||
/// <summary>[Editor-Only]
|
||||
/// A <see cref="TransitionLibraryWindowPage"/> for editing transition aliases.
|
||||
/// </summary>
|
||||
/// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibraryAliasesPage
|
||||
[Serializable]
|
||||
public class TransitionLibraryAliasesPage : TransitionLibraryWindowPage
|
||||
{
|
||||
/************************************************************************************************************************/
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 _ScrollPosition;
|
||||
|
||||
[NonSerialized]
|
||||
private bool _HasSorted;
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string DisplayName
|
||||
=> "Transition Aliases";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string HelpTooltip
|
||||
=> "Aliases are custom names which can be used to refer to transitions instead of direct references.";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int Index
|
||||
=> 2;
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
private static readonly List<Rect>
|
||||
TransitionAreas = new();
|
||||
|
||||
private static float ButtonWidth
|
||||
=> LineHeight * 4;
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnGUI(Rect area)
|
||||
{
|
||||
var definition = Window.Data;
|
||||
|
||||
if (!_HasSorted)
|
||||
{
|
||||
_HasSorted = true;
|
||||
definition.SortAliases();
|
||||
}
|
||||
|
||||
var currentEvent = Event.current;
|
||||
var isRepaint = currentEvent.type == EventType.Repaint;
|
||||
if (isRepaint)
|
||||
TransitionAreas.Clear();
|
||||
|
||||
area.yMin += StandardSpacing;
|
||||
area.xMin += StandardSpacing;
|
||||
area.xMax -= StandardSpacing;
|
||||
|
||||
var items = Window.Items;
|
||||
var aliases = definition.Aliases;
|
||||
|
||||
var viewArea = new Rect(
|
||||
0,
|
||||
0,
|
||||
area.width,
|
||||
CalculateHeight(1 + items.Count + aliases.Length) + StandardSpacing);
|
||||
|
||||
if (viewArea.height > area.height)
|
||||
viewArea.width -= GUI.skin.verticalScrollbar.fixedWidth;
|
||||
|
||||
_ScrollPosition = GUI.BeginScrollView(area, _ScrollPosition, viewArea);
|
||||
|
||||
viewArea.height = LineHeight;
|
||||
|
||||
DoAliasAllGUI(viewArea);
|
||||
|
||||
NextVerticalArea(ref viewArea);
|
||||
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
if (isRepaint)
|
||||
TransitionAreas.Add(viewArea);
|
||||
|
||||
DoItemGUI(ref viewArea, i, currentEvent);
|
||||
}
|
||||
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
private void DoItemGUI(
|
||||
ref Rect area,
|
||||
int itemIndex,
|
||||
Event currentEvent)
|
||||
{
|
||||
var totalTransitionArea = area;
|
||||
var items = Window.Items;
|
||||
|
||||
var item = items.GetItem(itemIndex);
|
||||
if (item is TransitionAssetBase transition)
|
||||
{
|
||||
var hasGroup = items.GetGroup(itemIndex) != null;
|
||||
if (hasGroup)
|
||||
area.xMin += IndentSize;
|
||||
|
||||
var transitions = Window.Data.Transitions;
|
||||
var transitionIndex = Array.IndexOf(transitions, transition);
|
||||
|
||||
DoTransitionGUI(area, transition, transitionIndex);
|
||||
|
||||
NextVerticalArea(ref area);
|
||||
|
||||
DoAliasGUI(ref area, transitionIndex);
|
||||
|
||||
if (hasGroup)
|
||||
area.xMin -= IndentSize;
|
||||
}
|
||||
else if (item is TransitionGroup group)
|
||||
{
|
||||
var groupArea = area;
|
||||
NextVerticalArea(ref area);
|
||||
|
||||
var foldoutArea = StealFromLeft(ref groupArea, LineHeight, StandardSpacing);
|
||||
|
||||
TransitionModifierTableGUI.HandleTransitionLabelInput(
|
||||
ref groupArea,
|
||||
Window,
|
||||
group,
|
||||
SelectionType.Group,
|
||||
CalculateTarget);
|
||||
|
||||
GUI.Label(groupArea, group.Name);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
group.IsExpanded = EditorGUI.Foldout(foldoutArea, group.IsExpanded, GUIContent.none);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
Window.Selection.Select(Window, group, group.Index, SelectionType.Group);
|
||||
}
|
||||
|
||||
// Highlights.
|
||||
|
||||
totalTransitionArea.yMax = area.yMin - StandardSpacing;
|
||||
|
||||
var selected = Window.Selection.Selected == item;
|
||||
var hover = totalTransitionArea.Contains(currentEvent.mousePosition);
|
||||
|
||||
Window.Highlighter.DrawHighlightGUI(totalTransitionArea, selected, hover);
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <summary>Draws <see cref="TransitionLibraryDefinition.AliasAllTransitions"/>.</summary>
|
||||
private void DoAliasAllGUI(Rect area)
|
||||
{
|
||||
var definition = Window.Data;
|
||||
|
||||
using (var label = PooledGUIContent.Acquire(
|
||||
"Alias All Transitions",
|
||||
TransitionLibraryDefinition.AliasAllTransitionsTooltip))
|
||||
definition.AliasAllTransitions = EditorGUI.Toggle(area, label, definition.AliasAllTransitions);
|
||||
|
||||
if (TryUseClickEvent(area, 0))
|
||||
definition.AliasAllTransitions = !definition.AliasAllTransitions;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <summary>Draws a `transition`.</summary>
|
||||
private void DoTransitionGUI(Rect area, TransitionAssetBase transition, int index)
|
||||
{
|
||||
var addArea = StealFromLeft(ref area, ButtonWidth, StandardSpacing);
|
||||
|
||||
TransitionModifierTableGUI.HandleTransitionLabelInput(
|
||||
ref area,
|
||||
Window,
|
||||
transition,
|
||||
SelectionType.ToTransition,
|
||||
CalculateTarget);
|
||||
|
||||
var typeArea = StealFromRight(ref area, area.width * 0.5f, StandardSpacing);
|
||||
|
||||
var label = transition.GetCachedName();
|
||||
GUI.Label(area, label);
|
||||
|
||||
var wrappedTransition = transition.GetTransition();
|
||||
var type = wrappedTransition != null
|
||||
? wrappedTransition.GetType().GetNameCS(false)
|
||||
: "Null";
|
||||
GUI.Label(typeArea, type);
|
||||
|
||||
if (GUI.Button(addArea, "Add"))
|
||||
{
|
||||
var alias = new NamedIndex(null, index);
|
||||
Window.RecordUndo().AddAlias(alias);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <summary>Calculates the target index for a drag and drop operation.</summary>
|
||||
private static ListTargetCalculation CalculateTarget(
|
||||
Rect area,
|
||||
int index,
|
||||
Event currentEvent)
|
||||
{
|
||||
var y = currentEvent.mousePosition.y;
|
||||
for (int i = 0; i < TransitionAreas.Count; i++)
|
||||
{
|
||||
area = TransitionAreas[i];
|
||||
var yMax = area.yMax;
|
||||
if (y > yMax)
|
||||
continue;
|
||||
|
||||
return new(
|
||||
i,
|
||||
Mathf.InverseLerp(area.y, yMax, y));
|
||||
}
|
||||
|
||||
return new(TransitionAreas.Count, 1);
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
/// <summary>Draws all aliases for the specified `transitionIndex`.</summary>
|
||||
private void DoAliasGUI(ref Rect area, int transitionIndex)
|
||||
{
|
||||
var aliases = Window.Data.Aliases;
|
||||
for (int i = 0; i < aliases.Length; i++)
|
||||
{
|
||||
var alias = aliases[i];
|
||||
|
||||
if (alias.Index != transitionIndex)
|
||||
continue;
|
||||
|
||||
DoAliasGUI(area, alias, i);
|
||||
|
||||
NextVerticalArea(ref area);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Draws an `alias`.</summary>
|
||||
private void DoAliasGUI(Rect area, NamedIndex alias, int aliasIndex)
|
||||
{
|
||||
var removeArea = StealFromLeft(ref area, ButtonWidth, StandardSpacing);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var name = StringAssetDrawer.DrawGUI(area, GUIContent.none, alias.Name, Window.SourceObject, out _);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Window.RecordUndo().Aliases[aliasIndex] = alias.With(name as StringAsset);
|
||||
}
|
||||
|
||||
if (GUI.Button(removeArea, "Remove"))
|
||||
{
|
||||
Window.RecordUndo().RemoveAlias(aliasIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user