playtest-unity/playtest/Library/PackageCache/com.unity.settings-manager@.../Editor/SettingsGUILayout.cs

588 lines
29 KiB
C#
Raw Permalink Normal View History

2023-06-21 13:28:15 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.SettingsManagement
{
static class SettingsGUIStyles
{
const string k_SettingsGearIcon = "Packages/" + UserSettings.packageName + "/Content/Options.png";
static bool s_Initialized;
public static GUIStyle s_SettingsGizmo;
public static GUIStyle s_SettingsArea;
public static GUIStyle s_IndentedSettingBlock;
static void Init()
{
if (s_Initialized)
return;
s_Initialized = true;
s_SettingsGizmo = new GUIStyle()
{
normal = new GUIStyleState()
{
background = AssetDatabase.LoadAssetAtPath<Texture2D>(k_SettingsGearIcon)
},
fixedWidth = 14,
fixedHeight = 14,
padding = new RectOffset(0, 0, 0, 0),
margin = new RectOffset(4, 4, 4, 4),
imagePosition = ImagePosition.ImageOnly
};
s_SettingsArea = new GUIStyle()
{
margin = new RectOffset(6, 6, 0, 0)
};
s_IndentedSettingBlock = new GUIStyle()
{
padding = new RectOffset(16, 0, 0, 0)
};
}
public static GUIStyle settingsGizmo
{
get
{
Init();
return s_SettingsGizmo;
}
}
public static GUIStyle settingsArea
{
get
{
Init();
return s_SettingsArea;
}
}
public static GUIStyle indentedSettingBlock
{
get
{
Init();
return s_IndentedSettingBlock;
}
}
}
/// <summary>
/// Provides extension methods for <see cref="UnityEngine.GUILayout"/> that also implement settings-specific functionality.
/// </summary>
public static class SettingsGUILayout
{
/// <summary>
/// Provides methods for creating and managing indented GUI sections.
/// </summary>
public class IndentedGroup : IDisposable
{
bool m_IsDisposed;
/// <summary>
/// Creates an indented GUI section.
/// </summary>
public IndentedGroup()
{
EditorGUIUtility.labelWidth -= SettingsGUIStyles.indentedSettingBlock.padding.left - 4;
GUILayout.BeginVertical(SettingsGUIStyles.indentedSettingBlock);
}
/// <summary>
/// Creates an indented GUI section with a label.
/// </summary>
/// <param name="label">The name of the section to display in the UI as a label. </param>
public IndentedGroup(string label)
{
GUILayout.Label(label);
EditorGUIUtility.labelWidth -= SettingsGUIStyles.indentedSettingBlock.padding.left - 4;
GUILayout.BeginVertical(SettingsGUIStyles.indentedSettingBlock);
}
/// <summary>
/// Reverts the GUI indent back to its original value.
/// </summary>
public void Dispose()
{
if (m_IsDisposed)
return;
m_IsDisposed = true;
GUILayout.EndVertical();
EditorGUIUtility.labelWidth += SettingsGUIStyles.indentedSettingBlock.padding.left - 4;
}
}
internal static HashSet<string> s_Keywords = null;
internal static bool MatchSearchGroups(string searchContext, string label)
{
if (s_Keywords != null)
{
foreach (var keyword in label.Split(' '))
s_Keywords.Add(keyword);
}
if (searchContext == null)
return true;
var ctx = searchContext.Trim();
if (string.IsNullOrEmpty(ctx))
return true;
var split = searchContext.Split(' ');
return split.Any(x => !string.IsNullOrEmpty(x) && label.IndexOf(x, StringComparison.InvariantCultureIgnoreCase) > -1);
}
internal static bool DebugModeFilter(IUserSetting pref)
{
if (!EditorPrefs.GetBool("DeveloperMode", false))
return true;
if (pref.scope == SettingsScope.Project && UserSettingsProvider.showProjectSettings)
return true;
if (pref.scope == SettingsScope.User && UserSettingsProvider.showUserSettings)
return true;
return false;
}
/// <summary>
/// Creates a slider that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SearchableSlider(GUIContent label, float value, float min, float max, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.Slider(label, value, min, max);
}
/// <summary>
/// Creates a slider that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SearchableSlider(string label, float value, float min, float max, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.Slider(label, value, min, max);
}
/// <summary>
/// Creates a float field that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SearchableFloatField(GUIContent label, float value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.FloatField(label, value);
}
/// <summary>
/// Creates a float field that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SearchableFloatField(string label, float value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.FloatField(label, value);
}
/// <summary>
/// Creates an int field that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SearchableIntField(GUIContent label, int value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.IntField(label, value);
}
/// <summary>
/// Creates an int field that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SearchableIntField(string label, int value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.IntField(label, value);
}
/// <summary>
/// Creates a toggle field that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static bool SearchableToggle(GUIContent label, bool value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.Toggle(label, value);
}
/// <summary>
/// Creates a toggle field that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static bool SearchableToggle(string label, bool value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.Toggle(label, value);
}
/// <summary>
/// Creates a text field that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static string SearchableTextField(GUIContent label, string value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.TextField(label, value);
}
/// <summary>
/// Creates a text field that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static string SearchableTextField(string label, string value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.TextField(label, value);
}
/// <summary>
/// Creates a color field that implements search filtering.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static Color SearchableColorField(GUIContent label, Color value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label.text))
return value;
return EditorGUILayout.ColorField(label, value);
}
/// <summary>
/// Creates a color field that implements search filtering.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static Color SearchableColorField(string label, Color value, string searchContext)
{
if (!MatchSearchGroups(searchContext, label))
return value;
return EditorGUILayout.ColorField(label, value);
}
/// <summary>
/// Creates a float slider that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SettingsSlider(GUIContent label, UserSetting<float> value, float min, float max, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.Slider(label, value, min, max);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a float slider that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SettingsSlider(string label, UserSetting<float> value, float min, float max, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.Slider(label, value, min, max);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates an int slider that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SettingsSlider(GUIContent label, UserSetting<int> value, int min, int max, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.IntSlider(label, value, min, max);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates an int slider that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="min">The value at the left end of the slider.</param>
/// <param name="max">The value at the right end of the slider.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SettingsSlider(string label, UserSetting<int> value, int min, int max, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.IntSlider(label, value, min, max);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a float field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SettingsFloatField(GUIContent label, UserSetting<float> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.FloatField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a float field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static float SettingsFloatField(string label, UserSetting<float> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.FloatField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates an integer field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SettingsIntField(GUIContent label, UserSetting<int> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.IntField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates an integer field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static int SettingsIntField(string label, UserSetting<int> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.IntField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a boolean toggle field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static bool SettingsToggle(GUIContent label, UserSetting<bool> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.Toggle(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a boolean toggle field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static bool SettingsToggle(string label, UserSetting<bool> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.Toggle(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a text field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static string SettingsTextField(GUIContent label, UserSetting<string> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.TextField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a text field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static string SettingsTextField(string label, UserSetting<string> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.TextField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a color field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a <see cref="UnityEngine.GUIContent"/> instance to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static Color SettingsColorField(GUIContent label, UserSetting<Color> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label.text))
return value;
var res = EditorGUILayout.ColorField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Creates a color field that implements search filtering and a <see cref="DoResetContextMenuForLastRect">Reset</see> context menu entry.
/// </summary>
/// <param name="label">Specify a string to set the label that appears beside the value field. </param>
/// <param name="value">The value to edit.</param>
/// <param name="searchContext">A string representing the current search query. Empty or null strings match any value.</param>
/// <returns>The value set by the user.</returns>
public static Color SettingsColorField(string label, UserSetting<Color> value, string searchContext)
{
if (!DebugModeFilter(value) || !MatchSearchGroups(searchContext, label))
return value;
var res = EditorGUILayout.ColorField(label, value);
DoResetContextMenuForLastRect(value);
return res;
}
/// <summary>
/// Implements a "Reset" context menu entry for the specified user setting.
/// using the rect from the last automatic layout.
/// </summary>
/// <param name="setting">The target setting for the "Reset" context menu entry.</param>
public static void DoResetContextMenuForLastRect(IUserSetting setting)
{
DoResetContextMenu(GUILayoutUtility.GetLastRect(), setting);
}
static void DoResetContextMenu(Rect rect, IUserSetting pref)
{
var evt = Event.current;
if (evt.type == EventType.ContextClick && rect.Contains(evt.mousePosition))
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("Reset [" + pref.scope + "] " + pref.key), false, () =>
{
pref.Reset(true);
});
menu.ShowAsContext();
}
}
}
}