Repository URL to install this package:
Version:
1.3.1 ▾
|
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Fluctio.FluctioSim.Common.Icons;
using Fluctio.FluctioSim.EditorUtils.EditorGeneral;
using Fluctio.FluctioSim.Utils.Extensions;
using Fluctio.FluctioSim.Utils.General;
using JetBrains.Annotations;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
using UnityEngine.UIElements;
namespace Fluctio.FluctioSim.EditorUtils.Gui
{
public static class EditorGUIExtensions
{
#region General property drawing
private static SerializedProperty FindFieldOrPropertyInternal(Func<string, SerializedProperty> fieldOnlyFinder, string fieldOrPropertyName) =>
fieldOnlyFinder(fieldOrPropertyName) ?? fieldOnlyFinder(Util.GetBackingFieldName(fieldOrPropertyName));
public static SerializedProperty FindFieldOrProperty(this SerializedObject serializedObject, string fieldOrPropertyName) =>
FindFieldOrPropertyInternal(serializedObject.FindProperty, fieldOrPropertyName);
public static SerializedProperty FindFieldOrProperty(this SerializedProperty serializedProperty, string fieldOrPropertyName) =>
FindFieldOrPropertyInternal(serializedProperty.FindPropertyRelative, fieldOrPropertyName);
private static bool DrawPropertiesInternal(
SerializedObject serializedObject,
Func<string, SerializedProperty> fieldOrPropertyFinder,
params string[] propertyNames)
{
serializedObject.Update();
foreach (var propertyName in propertyNames)
{
var fieldOrProperty = fieldOrPropertyFinder(propertyName);
if (fieldOrProperty == null)
{
// ReSharper disable once Unity.PerformanceCriticalCodeInvocation
Debug.LogWarning($"Could not find field or property '{propertyName}'");
continue;
}
EditorGUILayout.PropertyField(fieldOrProperty, true);
}
return serializedObject.ApplyModifiedProperties();
}
public static bool DrawProperties(this SerializedObject serializedObject, params string[] propertyNames) =>
DrawPropertiesInternal(serializedObject, serializedObject.FindFieldOrProperty, propertyNames);
public static bool DrawProperties(this SerializedProperty serializedProperty, params string[] propertyNames) =>
DrawPropertiesInternal(serializedProperty.serializedObject, serializedProperty.FindFieldOrProperty, propertyNames);
#endregion
#region LeftClickButton
public static bool LeftClickButton(GUIContent label, [CanBeNull] GUIStyle style = null, params GUILayoutOption[] layoutOptions)
{
style ??= GUI.skin.button;
var isButtonClicked = GUILayout.Button(label, style, layoutOptions);
EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link, GUIUtility.GetControlID(FocusType.Passive));
var isLeftButton = Event.current.button == (int)MouseButton.LeftMouse;
return isButtonClicked && isLeftButton;
}
public static bool LeftClickButton(GUIContent label, params GUILayoutOption[] layoutOptions) =>
LeftClickButton(label, null, layoutOptions);
public static bool LeftClickButton(string label, params GUILayoutOption[] layoutOptions) =>
LeftClickButton(new GUIContent(label), layoutOptions);
public static bool LeftClickButton(Texture2D label, params GUILayoutOption[] layoutOptions) =>
LeftClickButton(new GUIContent(label), layoutOptions);
public static bool LeftClickButton(string label, GUIStyle style, params GUILayoutOption[] layoutOptions) =>
LeftClickButton(new GUIContent(label), style, layoutOptions);
public static bool LeftClickButton(Texture2D label, GUIStyle style, params GUILayoutOption[] layoutOptions) =>
LeftClickButton(new GUIContent(label), style, layoutOptions);
#endregion
#region TypedDropdown
public static T TypedDropdown<T>(string label, List<T> values, T oldValue, Func<T, string> displayNameGetter)
{
var oldIndex = values.FindIndex(value => Equals(value, oldValue));
var displayNames = values.Select(displayNameGetter);
if (oldIndex < 0)
{
var oldDisplayName = displayNameGetter(oldValue);
EditorGUILayout.HelpBox($"\"{oldDisplayName}\" is not a valid value for \"{label}\"", MessageType.Warning);
displayNames = displayNames.Append(oldDisplayName);
oldIndex = values.Count;
}
var newIndex = EditorGUILayout.Popup(label, oldIndex, displayNames.ToArray());
return newIndex < values.Count ? values[newIndex] : oldValue;
}
public static string TypedDropdown(string label, List<string> values, string oldValue) =>
TypedDropdown(label, values, oldValue, Util.Identity);
public static T TypedDropdown<T>(string label, T oldValue) where T: Enum
{
var values = ReflectionExtensions.GetEnumOptions<T>().ToList();
return TypedDropdown(label, values, oldValue, EnumDisplayGetter);
string EnumDisplayGetter(T enumValue) => enumValue.AsField().GetDescription();
}
#endregion
#region Other
public static string FilePicker(string label, string currentValue, string extensions, string defaultDirectory = "")
{
using var horizontalScope = new EditorGUILayout.HorizontalScope();
var textFieldValue = EditorGUILayout.TextField(label, currentValue);
var isButtonClicked = EditorGUIExtensions.LeftClickButton(DefinedIcons.FilePicker, EditorUtil.InlineIconStyle);
if (!isButtonClicked)
{
return textFieldValue;
}
var directory = string.IsNullOrWhiteSpace(currentValue)
? defaultDirectory
: Path.GetDirectoryName(currentValue);
var filePanelValue = EditorUtility.OpenFilePanel(label, directory, extensions);
if (filePanelValue == "")
{
return currentValue;
}
EditorGUIUtility.editingTextField = false;
return filePanelValue;
}
public static void HorizontalLine() => EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
public static bool WebLink(string url, string text = null)
{
text ??= url;
var isClicked = EditorGUILayout.LinkButton(text);
if (isClicked)
{
Application.OpenURL(url);
}
return isClicked;
}
public static void Foldout(GUIContent label, AnimBool isOpen, Action drawAction, bool isFoldout = true, string additionalInfo = null)
{
if (!isFoldout)
{
GUILayout.Label(label);
drawAction();
return;
}
if (!isOpen.target && !string.IsNullOrWhiteSpace(additionalInfo))
{
label.text += $" ({additionalInfo})";
}
isOpen.target = EditorGUILayout.Foldout(isOpen.target, label, true);
using var fadeGroupScope = new EditorGUILayout.FadeGroupScope(isOpen.faded);
if (!isOpen.value)
{
return;
}
using var indentScope = new EditorGUI.IndentLevelScope();
drawAction();
}
public static void Foldout(string label, AnimBool isOpen, Action drawAction, bool isFoldout = true) =>
Foldout(new GUIContent(label), isOpen, drawAction, isFoldout);
public static void ThrowingDialog(string message, string ok = "OK", string cancel = "Cancel", string title = "Are you sure?", string exceptionMessage = "")
{
var isConfirmed = EditorUtility.DisplayDialog(title, message, ok, cancel);
if (!isConfirmed)
{
throw new OperationCanceledException(exceptionMessage);
}
}
#endregion
}
}