You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
9.7 KiB
220 lines
9.7 KiB
using System;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.HighDefinition;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UnityEditor.Rendering.HighDefinition
|
|
{
|
|
[CustomPropertyDrawer(typeof(FrameSettings))]
|
|
class FrameSettingsPropertyDrawer : PropertyDrawer
|
|
{
|
|
static class Styles
|
|
{
|
|
public const int labelWidth = 220;
|
|
|
|
public static readonly GUIContent[] headerContents = new GUIContent[]
|
|
{
|
|
FrameSettingsUI.renderingSettingsHeaderContent,
|
|
FrameSettingsUI.lightSettingsHeaderContent,
|
|
FrameSettingsUI.asyncComputeSettingsHeaderContent,
|
|
FrameSettingsUI.lightLoopSettingsHeaderContent
|
|
};
|
|
}
|
|
|
|
internal static string GetFrameSettingsFieldName(string name, int group) => $"UI_State_{nameof(FrameSettingsPropertyDrawer)}_{name}_{group}";
|
|
|
|
internal static bool IsExpended(string name, int group)
|
|
=> EditorPrefs.GetBool(GetFrameSettingsFieldName(name, group));
|
|
|
|
internal static void SetExpended(string name, int group, bool value)
|
|
=> EditorPrefs.SetBool(GetFrameSettingsFieldName(name, group), value);
|
|
|
|
float m_TotalHeight = 0f;
|
|
|
|
|
|
bool TryExtractUsageInfosFromAttribute(SerializedProperty dataProperty, out SerializedProperty maskProperty, out FrameSettingsRenderType defaultValues,
|
|
out HDRenderPipelineAsset hdrpAssetUsedForOverrideChecks)
|
|
{
|
|
maskProperty = null;
|
|
defaultValues = default;
|
|
hdrpAssetUsedForOverrideChecks = null;
|
|
|
|
Type hostType;
|
|
var serialisedObjectType = dataProperty.serializedObject.targetObject.GetType();
|
|
var baseLength = dataProperty.propertyPath.LastIndexOf('.');
|
|
string basePath = null;
|
|
string fieldName;
|
|
if (baseLength == -1)
|
|
{
|
|
fieldName = dataProperty.propertyPath;
|
|
hostType = serialisedObjectType;
|
|
}
|
|
else
|
|
{
|
|
basePath = dataProperty.propertyPath.Substring(0, baseLength);
|
|
fieldName = dataProperty.propertyPath.Substring(baseLength + 1);
|
|
hostType = dataProperty.serializedObject.FindProperty(basePath).boxedValue.GetType();
|
|
}
|
|
|
|
var attributes = hostType.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|
.GetCustomAttributes(typeof(UseOverrideMaskAttribute), true);
|
|
if (attributes.Length == 0)
|
|
return false;
|
|
|
|
var customPath = ((UseOverrideMaskAttribute)attributes[0]).pathToOverrideMask;
|
|
maskProperty = customPath == null ? null : dataProperty.serializedObject.FindProperty($"{(basePath == null ? "" : $"{basePath}.")}{customPath}");
|
|
if (maskProperty == null)
|
|
{
|
|
Debug.LogError($"Wrong serialization path set: [{nameof(UseOverrideMaskAttribute)}({customPath})]. Ignoring mask");
|
|
return false;
|
|
}
|
|
|
|
defaultValues = ((UseOverrideMaskAttribute)attributes[0]).defaultValuesToUse;
|
|
if (serialisedObjectType == typeof(HDRenderPipelineAsset))
|
|
{
|
|
// When drawing the inspector of a selected HDRPAsset in Project windows, use itself for checks
|
|
hdrpAssetUsedForOverrideChecks = dataProperty.serializedObject.targetObject as HDRenderPipelineAsset;
|
|
}
|
|
else
|
|
{
|
|
// Else rely on GraphicsSettings are you should be in hdrp
|
|
hdrpAssetUsedForOverrideChecks = HDRenderPipeline.currentAsset;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
|
{
|
|
var data = new SerializedFrameSettings.Data(property);
|
|
FrameSettingsExtractedDatas.DataLinked boundInstance;
|
|
SerializedFrameSettings.Mask mask = null;
|
|
if (TryExtractUsageInfosFromAttribute(property, out var maskProperty, out var defaultValues, out var hdrpAssetUsedForOverrideChecks))
|
|
{
|
|
boundInstance = FrameSettingsExtractedDatas.CreateBoundInstance(data, defaultValues, hdrpAssetUsedForOverrideChecks);
|
|
mask = new SerializedFrameSettings.Mask(maskProperty, data);
|
|
}
|
|
else
|
|
{
|
|
boundInstance = FrameSettingsExtractedDatas.CreateBoundInstance(data, null, null);
|
|
}
|
|
|
|
var root = new VisualElement() { name = "frame-settings" };
|
|
|
|
var labelHeader = new Label(property.displayName) { tooltip = property.tooltip };
|
|
labelHeader.AddToClassList("frame-settings-header");
|
|
root.Add(labelHeader);
|
|
|
|
for (int i = 0; i < Styles.headerContents.Length; ++i)
|
|
{
|
|
var header = new HeaderFoldout()
|
|
{
|
|
text = Styles.headerContents[i].text,
|
|
tooltip = Styles.headerContents[i].tooltip,
|
|
name = GetFrameSettingsFieldName(property.displayName, i),
|
|
};
|
|
header.AddToClassList("frame-settings-section-header");
|
|
header.value = IsExpended(property.displayName, i);
|
|
var encapsulatedIndex = i;
|
|
header.RegisterValueChangedCallback(evt => SetExpended(property.displayName, encapsulatedIndex, evt.newValue));
|
|
header.contentContainer.Add(mask == null
|
|
? new FrameSettingsArea(boundInstance, i)
|
|
: new FrameSettingsAreaWithOverrides(boundInstance, mask, i));
|
|
root.Add(header);
|
|
}
|
|
|
|
root.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(string.Format(FrameSettingsArea.k_StylesheetPathFormat, "")));
|
|
|
|
return root;
|
|
}
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
var data = new SerializedFrameSettings.Data(property);
|
|
FrameSettingsExtractedDatas.DataLinked boundInstance;
|
|
SerializedFrameSettings.Mask mask = null;
|
|
if (TryExtractUsageInfosFromAttribute(property, out var maskProperty, out var defaultValues, out var hdrpAssetUsedForOverrideChecks))
|
|
{
|
|
boundInstance = FrameSettingsExtractedDatas.CreateBoundInstance(data, defaultValues, hdrpAssetUsedForOverrideChecks);
|
|
mask = new SerializedFrameSettings.Mask(maskProperty, data);
|
|
}
|
|
else
|
|
{
|
|
boundInstance = FrameSettingsExtractedDatas.CreateBoundInstance(data, null, null);
|
|
}
|
|
|
|
var oldWidth = EditorGUIUtility.labelWidth;
|
|
EditorGUIUtility.labelWidth = Styles.labelWidth;
|
|
EditorGUI.BeginProperty(position, label, property);
|
|
|
|
float y = position.y;
|
|
var subHeaderHeight = CoreEditorStyles.subSectionHeaderStyle.CalcHeight(label, position.width);
|
|
|
|
EditorGUI.LabelField(new Rect(position.x, y, position.width, subHeaderHeight), label, CoreEditorStyles.subSectionHeaderStyle);
|
|
y += subHeaderHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
for (int i = 0; i < Styles.headerContents.Length; ++i)
|
|
{
|
|
CoreEditorUtils.DrawSplitter(new Rect(position.x, y, position.width, 1f));
|
|
y += 1;
|
|
|
|
var oldExpendedState = IsExpended(property.displayName, i);
|
|
var newExpendedState = CoreEditorUtils.DrawHeaderFoldout(new Rect(position.x, y, position.width, subHeaderHeight), Styles.headerContents[i], oldExpendedState);
|
|
y += subHeaderHeight;
|
|
|
|
if (newExpendedState ^ oldExpendedState)
|
|
SetExpended(property.displayName, i, newExpendedState);
|
|
|
|
if (newExpendedState)
|
|
{
|
|
y += EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
if (mask == null)
|
|
FrameSettingsAreaImGUI.DrawWithoutOverride(new Rect(position.x, y, position.width, 0), boundInstance, i);
|
|
else
|
|
FrameSettingsAreaImGUI.DrawWithOverride(new Rect(position.x, y, position.width, 0), boundInstance, i, mask);
|
|
float areaHeight = FrameSettingsAreaImGUI.CalcHeightWithoutOverride(i);
|
|
y += areaHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
}
|
|
}
|
|
|
|
CoreEditorUtils.DrawSplitter(new Rect(position.x, y, position.width, 1f));
|
|
y += 1;
|
|
|
|
m_TotalHeight = y - position.y;
|
|
|
|
EditorGUI.EndProperty();
|
|
|
|
EditorGUIUtility.labelWidth = oldWidth;
|
|
}
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
{
|
|
return m_TotalHeight;
|
|
}
|
|
}
|
|
|
|
|
|
[CustomPropertyDrawer(typeof(FrameSettingsOverrideMask))]
|
|
class FrameSettingsOverrideMaskPropertyDrawer : PropertyDrawer
|
|
{
|
|
static readonly GUIContent k_Label = EditorGUIUtility.TrTextContent("Unavailable",
|
|
$"{nameof(FrameSettingsOverrideMask)} should not be displayed directly. Use [{nameof(UseOverrideMaskAttribute)}(pathToMask)] instead.");
|
|
|
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
|
{
|
|
var label2 = new Label($"{property.displayName} {k_Label.text}") { tooltip = k_Label.tooltip };
|
|
label2.SetEnabled(false);
|
|
return label2;
|
|
}
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
bool guiState = GUI.enabled;
|
|
GUI.enabled = false;
|
|
EditorGUI.LabelField(position, label, k_Label);
|
|
GUI.enabled = guiState;
|
|
}
|
|
}
|
|
}
|