using System;
using UnityEngine;
using UnityEngine.Splines;
namespace UnityEditor.Splines
{
///
/// Contains IMGUI controls for editing Spline data.
///
public static class SplineGUI
{
static GUIContent s_TempContent = new GUIContent();
static string[] s_SplineIndexPopupContents = new string[1] { "Spline 0" };
internal static GUIContent TempContent(string label, string tooltip = null, Texture2D image = null)
{
s_TempContent.text = label;
s_TempContent.tooltip = tooltip;
s_TempContent.image = image;
return s_TempContent;
}
///
/// Creates a dropdown to select an index between 0 and the count of contained in the
/// provided .
///
/// A that determines how many splines are available in
/// the popup selector.
/// The label to use for this property. If null, the property display name is used.
/// The rectangle on the screen to use for the field.
/// A SerializedProperty that stores an integer value.
/// An exception is thrown if is not an integer
/// field.
/// The type implementing .
public static void SplineIndexField(Rect rect, SerializedProperty property, GUIContent label, T container) where T : ISplineContainer
{
SplineIndexField(rect, property, label, container == null ? 0 : container.Splines.Count);
}
///
/// Creates a dropdown to select an index between 0 and .
///
/// The rectangle on the screen to use for the field.
/// A SerializedProperty that stores an integer value.
/// The label to use for this property. If null, the property display name is used.
/// The number of splines available. In most cases, this is the size of
///
/// An exception is thrown if is not an integer
/// field.
public static void SplineIndexField(Rect rect, SerializedProperty property, GUIContent label, int splineCount)
{
if (property.propertyType != SerializedPropertyType.Integer)
throw new ArgumentException("Spline index property must be of type `int`.", nameof(property));
EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
property.intValue = SplineIndexPopup(rect, label == null ? property.displayName : label.text, property.intValue, splineCount);
EditorGUI.showMixedValue = false;
}
///
/// Creates a dropdown to select an index between 0 and .
///
/// An optional prefix label.
/// The number of splines available. In most cases, this is the size of
///
/// The rectangle on the screen to use for the field.
/// The current index.
/// The selected index.
public static int SplineIndexPopup(Rect rect, string label, int index, int splineCount)
{
if (splineCount != s_SplineIndexPopupContents.Length)
{
Array.Resize(ref s_SplineIndexPopupContents, splineCount);
for (int i = 0; i < splineCount; ++i)
s_SplineIndexPopupContents[i] = $"Spline {i}";
}
return Math.Min(
Math.Max(0, EditorGUI.IntPopup(rect, label, index, s_SplineIndexPopupContents, null)),
splineCount-1);
}
}
///
/// Provides IMGUI controls to edit Spline data.
///
public static class SplineGUILayout
{
///
/// Creates a dropdown to select an index between 0 and the count of contained in the
/// provided .
///
/// A that determines how many splines are available in
/// the popup selector.
/// A SerializedProperty that stores an integer value.
/// An exception is thrown if is not an integer
/// field.
/// The type implementing .
public static void SplineIndexField(SerializedProperty property, T container) where T : ISplineContainer
{
SplineIndexField(property, container == null ? 0 : container.Splines.Count);
}
///
/// Creates a dropdown to select an index between 0 and .
///
/// A SerializedProperty that stores an integer value.
/// The number of splines available. In most cases, this is the size of
///
/// An exception is thrown if is not an integer
/// field.
public static void SplineIndexField(SerializedProperty property, int splineCount)
{
if (property.propertyType != SerializedPropertyType.Integer)
throw new ArgumentException("Spline index property must be of type `int`.", nameof(property));
EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
property.intValue = SplineIndexPopup(property.displayName, property.intValue, splineCount);
EditorGUI.showMixedValue = false;
}
///
/// Creates a dropdown to select a spline index relative to .
///
/// An optional prefix label.
/// The current index.
/// A that determines how many splines are available in
/// the popup selector.
/// The type of .
/// The selected index.
public static int SplineIndexPopup(string label, int index, T container) where T : ISplineContainer
{
return SplineIndexPopup(label, index, container == null ? 0 : container.Splines.Count);
}
///
/// Creates a dropdown to select an index between 0 and .
///
/// An optional prefix label.
/// The number of splines available. In most cases, this is the size of
///
/// The current index.
/// The selected index.
public static int SplineIndexPopup(string label, int index, int splineCount)
{
var rect = GUILayoutUtility.GetRect(SplineGUI.TempContent(label), EditorStyles.popup);
return SplineGUI.SplineIndexPopup(rect, label, index, splineCount);
}
///
/// Creates a field for an embedded property. Embedded
/// is stored in the class and can be accessed through a string key value. Use this
/// function to expose an embedded through the Inspector.
///
/// The that holds the target.
/// The index of the target in the
/// array.
/// The type of data stored in the embedded
///
/// A string value used to identify and access embedded .
/// True if the property has children, is expanded, and includeChildren was set to false. Returns false otherwise.
public static bool EmbeddedSplineDataField(SplineContainer container, int index, EmbeddedSplineDataType type, string key)
{
return EmbeddedSplineDataField(null, container, index, type, key);
}
///
/// Creates a field for an embedded property. Embedded
/// is stored in the class and can be accessed through a string key value. Use this
/// function to expose an embedded through the Inspector.
///
/// An optional prefix label.
/// The that holds the target.
/// The index of the target in the
/// array.
/// The type of data stored in the embedded
///
/// A string value used to identify and access embedded .
/// True if the property has children, is expanded, and includeChildren was set to false. Returns false otherwise.
public static bool EmbeddedSplineDataField(GUIContent label,
SplineContainer container,
int index,
EmbeddedSplineDataType type,
string key)
{
if (container == null || index < 0 || index >= container.Splines.Count)
return false;
var property = SerializedPropertyUtility.GetEmbeddedSplineDataProperty(container, index, type, key);
property.serializedObject.Update();
EditorGUI.BeginChangeCheck();
var ret = EditorGUILayout.PropertyField(property, label);
if(EditorGUI.EndChangeCheck())
property.serializedObject.ApplyModifiedProperties();
return ret;
}
internal static void QuaternionField(Rect rect, GUIContent content, SerializedProperty property)
{
EditorGUI.BeginChangeCheck();
Quaternion value = SplineGUIUtility.GetQuaternionValue(property);
var result = EditorGUI.Vector3Field(rect, content, value.eulerAngles);
if (EditorGUI.EndChangeCheck())
SplineGUIUtility.SetQuaternionValue(property, Quaternion.Euler(result));
}
}
}