using System;
using UnityEngine;
namespace Uigenx.Animation
{
public enum UgxLoopMode
{
None = 0,
Loop = 1,
PingPong = 2,
}
/// How a play request behaves when the same clip is already running.
public enum UgxPlayMode
{
Restart = 0,
IgnoreIfPlaying = 1,
Queue = 2,
}
[Serializable]
public sealed class UgxKeyframe
{
[SerializeField] float timeMs;
/// Canonical USS value text for the animated property.
[SerializeField] string value;
[SerializeField] UgxEasingCurve easing;
public UgxKeyframe()
{
}
public UgxKeyframe(float timeMs, string value, UgxEasingCurve easing = default)
{
this.timeMs = timeMs;
this.value = value;
this.easing = easing;
}
public float TimeMs => timeMs;
public string Value => value;
public UgxEasingCurve Easing => easing;
}
///
/// One animated property on one element. An empty means the screen
/// root, so a clip can be reused by any screen that has the named element.
/// narrows the target to a sub element the control builds for itself,
/// such as the fill of a ProgressBar: those carry a USS class and no name, so a class is the
/// only way to reach one.
///
[Serializable]
public sealed class UgxTrack
{
[SerializeField] string targetName;
[SerializeField] string partClass;
[SerializeField] string property;
[SerializeField] UgxKeyframe[] keyframes = Array.Empty();
public UgxTrack()
{
}
public UgxTrack(string targetName, string property, params UgxKeyframe[] keyframes)
: this(targetName, null, property, keyframes)
{
}
public UgxTrack(string targetName, string partClass, string property,
params UgxKeyframe[] keyframes)
{
this.targetName = targetName;
this.partClass = partClass;
this.property = property;
this.keyframes = keyframes ?? Array.Empty();
}
public string TargetName => targetName;
/// USS class of the sub element inside the target, null when there is none.
public string PartClass => partClass;
public string Property => property;
public UgxKeyframe[] Keyframes => keyframes;
public bool TargetsSelf => string.IsNullOrEmpty(targetName);
public bool HasPart => !string.IsNullOrEmpty(partClass);
}
[Serializable]
public sealed class UgxClip
{
public static readonly UgxClip[] None = Array.Empty();
[SerializeField] string name;
[SerializeField] float durationMs = 300f;
[SerializeField] UgxLoopMode loop = UgxLoopMode.None;
[SerializeField] UgxTrack[] tracks = Array.Empty();
public UgxClip()
{
}
public UgxClip(string name, float durationMs, UgxLoopMode loop, params UgxTrack[] tracks)
{
this.name = name;
this.durationMs = durationMs;
this.loop = loop;
this.tracks = tracks ?? Array.Empty();
}
public string Name => name;
public float DurationMs => durationMs;
public UgxLoopMode Loop => loop;
public UgxTrack[] Tracks => tracks;
}
}