Files
zeling_v2/Assets/LWGUI-1.14.1/Editor/RevertableHelper.cs

189 lines
5.7 KiB
C#

// Copyright (c) Jason Ma
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace LWGUI
{
/// <summary>
/// Helpers for drawing Unreal Style Revertable Shader GUI
/// </summary>
public class RevertableHelper
{
public static readonly float revertButtonWidth = 15f;
public static float fieldWidth;
public static float labelWidth;
#region GUI Setting
public static void IndentRect(ref Rect rect)
{
rect.xMax -= RevertableHelper.revertButtonWidth;
}
public static Rect SplitRevertButtonRect(ref Rect rect, bool isCallInDrawer = false)
{
float defaultHeightWithoutDrawers = EditorGUIUtility.singleLineHeight;
var revertButtonRect = GetRevertButtonRect(defaultHeightWithoutDrawers, rect, isCallInDrawer);
IndentRect(ref rect);
return revertButtonRect;
}
public static Rect GetRevertButtonRect(float propHeight, Rect rect, bool isCallInDrawer = false)
{
if (isCallInDrawer) rect.xMax += revertButtonWidth;
var revertButtonRect = new Rect(rect.xMax - revertButtonWidth + 2f,
rect.yMax - propHeight * 0.5f - revertButtonWidth * 0.5f,
revertButtonWidth - 2f,
revertButtonWidth - 3f);
return revertButtonRect;
}
public static void InitRevertableGUIWidths()
{
EditorGUIUtility.fieldWidth += RevertableHelper.revertButtonWidth;
EditorGUIUtility.labelWidth -= RevertableHelper.revertButtonWidth;
RevertableHelper.fieldWidth = EditorGUIUtility.fieldWidth;
RevertableHelper.labelWidth = EditorGUIUtility.labelWidth;
}
public static void SetRevertableGUIWidths()
{
EditorGUIUtility.fieldWidth = RevertableHelper.fieldWidth;
EditorGUIUtility.labelWidth = RevertableHelper.labelWidth;
}
public static void FixGUIWidthMismatch(MaterialProperty.PropType propType, MaterialEditor materialEditor)
{
switch (propType)
{
case MaterialProperty.PropType.Texture:
case MaterialProperty.PropType.Range:
materialEditor.SetDefaultGUIWidths();
break;
default:
RevertableHelper.SetRevertableGUIWidths();
break;
}
}
#endregion
#region Property Handle
public static void SetPropertyToDefault(MaterialProperty defaultProp, MaterialProperty prop)
{
prop.vectorValue = defaultProp.vectorValue;
prop.colorValue = defaultProp.colorValue;
prop.floatValue = defaultProp.floatValue;
prop.textureValue = defaultProp.textureValue;
#if UNITY_2021_1_OR_NEWER
prop.intValue = defaultProp.intValue;
#endif
}
public static string GetPropertyDefaultValueText(MaterialProperty defaultProp)
{
string defaultText = String.Empty;
switch (defaultProp.type)
{
case MaterialProperty.PropType.Color:
defaultText += defaultProp.colorValue;
break;
case MaterialProperty.PropType.Float:
case MaterialProperty.PropType.Range:
defaultText += defaultProp.floatValue;
break;
#if UNITY_2021_1_OR_NEWER
case MaterialProperty.PropType.Int:
defaultText += defaultProp.intValue;
break;
#endif
case MaterialProperty.PropType.Texture:
defaultText += defaultProp.textureValue != null ? defaultProp.textureValue.name : "None";
break;
case MaterialProperty.PropType.Vector:
defaultText += defaultProp.vectorValue;
break;
}
return defaultText;
}
#endregion
#region Draw revert button
public static bool DrawRevertableProperty(Rect position, MaterialProperty prop, LWGUI lwgui, bool isHeader = false)
{
bool hasModified = prop.hasMixedValue;
var propDynamicData = lwgui.perFrameData.propertyDatas[prop.name];
var propStaticData = lwgui.perShaderData.propertyDatas[prop.name];
if (!hasModified)
hasModified = propDynamicData.hasModified;
if (!hasModified && isHeader)
hasModified = propDynamicData.hasChildrenModified;
var extraPropNames = lwgui.perShaderData.propertyDatas[prop.name].extraPropNames;
if (!hasModified && extraPropNames.Count > 0)
hasModified = extraPropNames.Any((extraPropName => lwgui.perFrameData.propertyDatas[extraPropName].hasModified));
if (!hasModified)
return false;
Rect rect = position;
if (DrawRevertButton(rect))
{
DoRevertProperty(prop, lwgui);
foreach (var childStaticData in propStaticData.children)
{
DoRevertProperty(lwgui.perFrameData.propertyDatas[childStaticData.name].property, lwgui);
foreach (var childChildStaticData in childStaticData.children)
DoRevertProperty(lwgui.perFrameData.propertyDatas[childChildStaticData.name].property, lwgui);
}
// refresh keywords
MaterialEditor.ApplyMaterialPropertyDrawers(lwgui.materialEditor.targets);
return true;
}
return false;
}
private static void DoRevertProperty(MaterialProperty prop, LWGUI lwgui)
{
var propDynamicData = lwgui.perFrameData.propertyDatas[prop.name];
var extraPropNames = lwgui.perShaderData.propertyDatas[prop.name].extraPropNames;
propDynamicData.hasRevertChanged = true;
SetPropertyToDefault(propDynamicData.defualtProperty, prop);
foreach (var extraPropName in extraPropNames)
{
var extraPropDynamicData = lwgui.perFrameData.propertyDatas[extraPropName];
extraPropDynamicData.hasRevertChanged = true;
SetPropertyToDefault(extraPropDynamicData.defualtProperty, extraPropDynamicData.property);
}
}
private static readonly Texture _icon = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("e7bc1130858d984488bca32b8512ca96"));
public static bool DrawRevertButton(Rect rect)
{
if (_icon == null) Debug.LogError("RevertIcon.png + meta is missing!");
GUI.DrawTexture(rect, _icon);
var e = Event.current;
if (e.type == UnityEngine.EventType.MouseDown && rect.Contains(e.mousePosition))
{
e.Use();
return true;
}
return false;
}
#endregion
}
}