升级水插件
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Crest Water System
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -15,7 +15,7 @@ namespace WaveHarmonic.Crest.Editor
|
||||
/// <summary>
|
||||
/// Provides general helper functions for the editor.
|
||||
/// </summary>
|
||||
static class EditorHelpers
|
||||
static partial class EditorHelpers
|
||||
{
|
||||
internal static ComputeShader s_VisualizeNegativeValuesShader;
|
||||
internal static ComputeShader VisualizeNegativeValuesShader
|
||||
@@ -227,27 +227,6 @@ namespace WaveHarmonic.Crest.Editor
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
|
||||
static readonly MethodInfo s_ButtonWithDropdownList = typeof(EditorGUI).GetMethod
|
||||
(
|
||||
"ButtonWithDropdownList",
|
||||
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
|
||||
null,
|
||||
new System.Type[] { typeof(GUIContent), typeof(string[]), typeof(GenericMenu.MenuFunction2), typeof(GUILayoutOption[]) },
|
||||
null
|
||||
);
|
||||
|
||||
static readonly GUILayoutOption[] s_GUILayoutOptionsZero;
|
||||
|
||||
public static bool ButtonWithDropdownList(GUIContent name, string[] names, GenericMenu.MenuFunction2 callback)
|
||||
{
|
||||
if (names == null)
|
||||
{
|
||||
return GUILayout.Button(name);
|
||||
}
|
||||
|
||||
return (bool)s_ButtonWithDropdownList.Invoke(null, new object[] { name, names, callback, s_GUILayoutOptionsZero });
|
||||
}
|
||||
}
|
||||
|
||||
static partial class Extensions
|
||||
@@ -269,4 +248,241 @@ namespace WaveHarmonic.Crest.Editor
|
||||
return tag.name;
|
||||
}
|
||||
}
|
||||
|
||||
static partial class EditorHelpers
|
||||
{
|
||||
const int k_ButtonDropDownWidth = 15;
|
||||
|
||||
static readonly GUIContent s_ButtonDropDownIcon = new(EditorGUIUtility.FindTexture("icon dropdown@2x"));
|
||||
static readonly PropertyInfo s_TopLevel = typeof(GUILayoutUtility).GetProperty("topLevel", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
static readonly MethodInfo s_GetLast = typeof(GUILayoutUtility).Assembly.GetType("UnityEngine.GUILayoutGroup").GetMethod("GetLast", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
// Only way to identify the caller is its rect.
|
||||
static Rect s_ButtonChooser;
|
||||
static int s_ButtonChoice = -2;
|
||||
|
||||
// Normal button or split button with dropdown.
|
||||
public static bool Button
|
||||
(
|
||||
GUIContent label,
|
||||
out int choice,
|
||||
string[] labels,
|
||||
bool disableMain = false,
|
||||
bool disableDropDown = false,
|
||||
bool centerLabel = false,
|
||||
bool expandWidth = true,
|
||||
int minimumWidth = 0
|
||||
)
|
||||
{
|
||||
choice = -2;
|
||||
var chosen = false;
|
||||
|
||||
var hasDropDown = labels?.Length > 0;
|
||||
var skin = GUI.skin.button;
|
||||
|
||||
using (new EditorGUI.DisabledGroupScope(disableMain))
|
||||
{
|
||||
var style = new GUIStyle(hasDropDown ? EditorStyles.miniButtonLeft : EditorStyles.miniButton)
|
||||
{
|
||||
padding = skin.padding,
|
||||
stretchHeight = skin.stretchHeight,
|
||||
fixedHeight = skin.fixedHeight
|
||||
};
|
||||
|
||||
var width = style.CalcSize(label).x + style.padding.left +
|
||||
style.padding.right + style.border.left + style.border.right;
|
||||
width = Mathf.Max(width, minimumWidth);
|
||||
// TODO: Add option to disable this (consistent width).
|
||||
if (!hasDropDown && minimumWidth > 0) width += k_ButtonDropDownWidth;
|
||||
if (centerLabel && hasDropDown) style.padding.left += k_ButtonDropDownWidth;
|
||||
|
||||
if (GUILayout.Button(label, style, expandWidth ? GUILayout.ExpandWidth(true) : GUILayout.Width(width)))
|
||||
{
|
||||
choice = -1;
|
||||
chosen = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDropDown)
|
||||
{
|
||||
using (new EditorGUI.DisabledGroupScope(disableDropDown))
|
||||
{
|
||||
// TODO: color interior border same as exterior (lighten).
|
||||
var style = new GUIStyle(EditorStyles.miniButtonRight)
|
||||
{
|
||||
padding = new(1, 1, 3, 3),
|
||||
stretchHeight = skin.stretchHeight,
|
||||
fixedHeight = skin.fixedHeight
|
||||
};
|
||||
|
||||
var rect = (Rect)s_GetLast.Invoke(s_TopLevel.GetValue(null), null);
|
||||
rect.width += k_ButtonDropDownWidth;
|
||||
|
||||
if (s_ButtonChoice > -1 && s_ButtonChooser == rect)
|
||||
{
|
||||
choice = s_ButtonChoice;
|
||||
chosen = true;
|
||||
s_ButtonChoice = -2;
|
||||
s_ButtonChooser = Rect.zero;
|
||||
}
|
||||
|
||||
if (GUILayout.Button(s_ButtonDropDownIcon, style, GUILayout.Width(k_ButtonDropDownWidth), GUILayout.ExpandHeight(true)))
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
{
|
||||
menu.AddItem(new(labels[i]), false, x => { s_ButtonChoice = (int)x; s_ButtonChooser = rect; }, i);
|
||||
}
|
||||
|
||||
menu.DropDown(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return chosen;
|
||||
}
|
||||
}
|
||||
|
||||
static partial class EditorHelpers
|
||||
{
|
||||
// Adapted from (public API may support this in future):
|
||||
// com.unity.splines@2.7.2/Editor/Components/SplineContainerEditor.cs
|
||||
static GUIStyle s_HelpLabelStyle;
|
||||
static GUIStyle HelpLabelStyle => s_HelpLabelStyle ??= new(EditorStyles.label)
|
||||
{
|
||||
wordWrap = EditorStyles.helpBox.wordWrap,
|
||||
fontSize = EditorStyles.helpBox.fontSize,
|
||||
padding = new(-2, 0, 0, 0),
|
||||
richText = true,
|
||||
};
|
||||
|
||||
static readonly MethodInfo s_GetHelpIcon = typeof(EditorGUIUtility).GetMethod("GetHelpIcon", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
internal static int? HelpBox
|
||||
(
|
||||
GUIContent message,
|
||||
MessageType type,
|
||||
GUIContent button = null,
|
||||
string[] buttons = null,
|
||||
bool buttonCenterLabel = false,
|
||||
int buttonMinimumWidth = 0
|
||||
)
|
||||
{
|
||||
return HelpBox
|
||||
(
|
||||
message,
|
||||
new GUIContent((Texture2D)s_GetHelpIcon.Invoke(null, new object[] { type })),
|
||||
button,
|
||||
buttons,
|
||||
buttonCenterLabel,
|
||||
buttonMinimumWidth
|
||||
);
|
||||
}
|
||||
|
||||
internal static int? HelpBox
|
||||
(
|
||||
GUIContent message,
|
||||
GUIContent icon,
|
||||
GUIContent button = null,
|
||||
string[] buttons = null,
|
||||
bool buttonCenterLabel = false,
|
||||
int buttonMinimumWidth = 0
|
||||
)
|
||||
{
|
||||
int? result = null;
|
||||
|
||||
// Box
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
|
||||
// Icon
|
||||
EditorGUIUtility.SetIconSize(new(32f, 32f));
|
||||
EditorGUILayout.LabelField(icon, GUILayout.Width(34), GUILayout.MinHeight(34), GUILayout.ExpandHeight(true));
|
||||
EditorGUIUtility.SetIconSize(Vector2.zero);
|
||||
|
||||
// Text
|
||||
EditorGUILayout.LabelField(message, HelpLabelStyle, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
|
||||
|
||||
// Button
|
||||
if (button != null)
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (Button(button, out var choice, buttons, centerLabel: buttonCenterLabel, minimumWidth: buttonMinimumWidth, expandWidth: false))
|
||||
{
|
||||
result = choice;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
static class Extensions
|
||||
{
|
||||
// Recursively find the field owner (instance).
|
||||
public static bool FindOwner(this FieldInfo field, ref object target)
|
||||
{
|
||||
if (field.DeclaringType.IsAssignableFrom(target.GetType()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return field.FindOwnerInFields(ref target);
|
||||
}
|
||||
|
||||
public static bool FindOwnerInFields(this FieldInfo targetField, ref object target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var fields = target.GetType()
|
||||
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.GetCustomAttribute<SerializeReference>() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = field.GetValue(target);
|
||||
if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (targetField.DeclaringType.IsAssignableFrom(value.GetType()))
|
||||
{
|
||||
target = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FindOwnerInFields(targetField, ref value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user