using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using System.Linq;
using System;
namespace UnityEditor.Rendering.HighDefinition
{
// A Material can be authored from the shader graph or by hand. When written by hand we need to provide an inspector.
// Such a Material will share some properties between it various variant (shader graph variant or hand authored variant).
// To create a such GUI, we provide Material UI Blocks, a modular API to create custom Material UI that allow
// you to reuse HDRP pre-defined blocks and access support header toggles automatically.
// Examples of such material UIs can be found in the classes UnlitGUI, LitGUI or LayeredLitGUI.
///
/// Wrapper to handle Material UI Blocks, it will handle initialization of the blocks when drawing the GUI.
///
public class MaterialUIBlockList : List
{
[System.NonSerialized]
bool m_Initialized = false;
Material[] m_Materials;
///
/// Parent of the ui block list, in case of nesting (Layered Lit material)
///
public MaterialUIBlockList parent;
///
/// List of materials currently selected in the inspector
///
public Material[] materials => m_Materials;
///
/// Construct a sub ui block list by passing the parent ui block list (useful for layered UI where ui blocks are nested)
///
///
public MaterialUIBlockList(MaterialUIBlockList parent) => this.parent = parent;
///
/// Construct a ui block list
///
public MaterialUIBlockList() : this(null) { }
///
/// Render the list of ui blocks
///
///
///
public void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
Initialize(materialEditor, properties);
foreach (var uiBlock in this)
{
try
{
// We load material properties at each frame because materials can be animated and to make undo/redo works
uiBlock.UpdateMaterialProperties(properties);
uiBlock.OnGUI();
}
// Never catch ExitGUIException as they are used to handle color picker and object pickers.
catch (ExitGUIException)
{
throw;
}
catch (Exception e)
{
Debug.LogException(e);
}
}
// Reset label width back to the default of 0 (fix UUM-66215)
// NOTE: Because of how EditorGUIUtility.labelWidth works, when the internal value is 0,
// we cannot read that value back from the property getter. So we just set it to 0 here.
EditorGUIUtility.labelWidth = 0;
}
///
/// Initialize the ui blocks
/// This function is called automatically by MaterialUIBlockList.OnGUI so you only need this when you want to render the UI Blocks in a custom order
///
/// Material editor instance.
/// The list of properties in the inspected material(s).
public void Initialize(MaterialEditor materialEditor, MaterialProperty[] properties)
{
if (!m_Initialized)
{
foreach (var uiBlock in this)
uiBlock.Initialize(materialEditor, properties, this);
m_Materials = materialEditor.targets.Select(target => target as Material).ToArray();
m_Initialized = true;
}
}
///
/// Fetch the first ui block of type T in the current list of material blocks
///
/// MaterialUIBlock type
///
public T FetchUIBlock() where T : MaterialUIBlock
{
return this.FirstOrDefault(uiBlock => uiBlock is T) as T;
}
}
}