using System;
using System.Linq;
using UnityEngine.Assertions;
namespace UnityEngine.Rendering
{
///
/// The `DebugUI` class defines a collection of debug UI components that are useful for debugging and profiling Rendering features
///
///
/// Widgets can be added to the UI, customized, and manipulated at runtime or during editor sessions. The class supports various
/// widget types, including buttons, read-only value fields, and progress bars. It also provides mechanisms for organizing these
/// widgets into containers. Each widget has a set of flags to control its visibility and behavior depending on whether it is
/// used in the editor or at runtime. The widgets can also contain callbacks for conditional visibility at runtime.
/// Important Notes:
/// - Widgets can be nested inside containers, allowing for organized groupings of debug UI elements.
/// - Widgets may be runtime-only, editor-only, or both, allowing them to behave differently depending on the application's
/// state (e.g., whether it is in the editor or playing at runtime).
/// - `DebugUI` also includes helper methods for widget initialization, such as compact initialization using the `NameAndTooltip` struct.
///
/// This API lets you do the following:
/// - Specify widget behavior such as "EditorOnly", "RuntimeOnly", "EditorForceUpdate", and "FrequentlyUsed".
/// - Show dynamic data with optional formatting.
/// - Specify delegate functions to show or hide widgets
///
/// Related Resources:
/// - [Debug UI Overview](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/features/rendering-debugger.html)
/// - [Rendering Debugger Controls](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/features/rendering-debugger-add-controls.html).
/// - [Using Rendering Debugger](https://docs.unity.cn/Packages/com.unity.render-pipelines.high-definition@16.0/manual/use-the-rendering-debugger.html).
///
///
///
/// using UnityEngine;
/// using UnityEngine.Rendering;
///
/// public class DebugUIExample : MonoBehaviour
/// {
/// private DebugUI.Button button;
/// private DebugUI.Value timeValue;
///
/// void Start()
/// {
/// // Create a button widget that logs a message when you select it
/// button = new DebugUI.Button
/// {
/// displayName = "Log Message Button",
/// action = () => Debug.Log("Button selected"),
/// isHiddenCallback = () => true,
/// };
///
/// // Create a value widget that displays the current time
/// timeValue = new DebugUI.Value
/// {
/// // Set the display label
/// displayName = "Current Time",
///
/// // Set the format for the time
/// getter = () => System.DateTime.Now.ToString("HH:mm:ss"),
///
/// // Set the value to refresh every second
/// refreshRate = 1f
/// };
///
/// // Add widgets to the UI (assuming a panel or container exists)
/// // ....
/// }
/// }
///
///
public partial class DebugUI
{
///
/// A column of checkboxes for enabling and disabling flags.
///
[Flags]
public enum Flags
{
///
/// None.
///
None = 0,
///
/// This widget is Editor only.
///
EditorOnly = 1 << 1,
///
/// This widget is Runtime only.
///
RuntimeOnly = 1 << 2,
///
/// This widget will force the Debug Editor Window refresh.
///
EditorForceUpdate = 1 << 3,
///
/// This widget will appear in the section "Frequently Used"
///
FrequentlyUsed = 1 << 4
}
///
/// Base class for all debug UI widgets.
///
public abstract class Widget
{
// Set to null until it's added to a panel, be careful
///
/// Panels containing the widget.
///
protected Panel m_Panel;
///
/// Panels containing the widget.
///
public virtual Panel panel
{
get { return m_Panel; }
internal set { m_Panel = value; }
}
///
/// Parent container.
///
protected IContainer m_Parent;
///
/// Parent container.
///
public virtual IContainer parent
{
get { return m_Parent; }
internal set { m_Parent = value; }
}
///
/// Flags for the widget.
///
public Flags flags { get; set; }
///
/// Display name.
///
public string displayName { get; set; }
///
/// Tooltip.
///
public string tooltip { get; set; }
///
/// Path of the widget.
///
public string queryPath { get; private set; }
///
/// True if the widget is Editor only.
///
public bool isEditorOnly => flags.HasFlag(Flags.EditorOnly);
///
/// True if the widget is Runtime only.
///
public bool isRuntimeOnly => flags.HasFlag(Flags.RuntimeOnly);
///
/// True if the widget is inactive in the editor (i.e. widget is runtime only and the application is not 'Playing').
///
public bool isInactiveInEditor => (isRuntimeOnly && !Application.isPlaying);
///
/// Optional delegate that can be used to conditionally hide widgets at runtime (e.g. due to state of other widgets).
///
public Func isHiddenCallback;
///
/// If shouldHideDelegate has been set and returns true, the widget is hidden from the UI.
///
public bool isHidden => isHiddenCallback?.Invoke() ?? false;
internal virtual void GenerateQueryPath()
{
queryPath = displayName.Trim();
if (m_Parent != null)
queryPath = m_Parent.queryPath + " -> " + queryPath;
}
///
/// Returns the hash code of the widget.
///
/// The hash code of the widget.
public override int GetHashCode()
{
return queryPath.GetHashCode() ^ isHidden.GetHashCode();
}
///
/// Helper struct to allow more compact initialization of widgets.
///
public struct NameAndTooltip
{
///
/// The name
///
public string name;
///
/// The tooltip
///
public string tooltip;
}
///
/// Helper setter to allow more compact initialization of widgets.
///
public NameAndTooltip nameAndTooltip
{
set
{
displayName = value.name;
tooltip = value.tooltip;
}
}
}
///
/// Interface for widgets that can contain other widgets.
///
public interface IContainer
{
///
/// List of children of the container.
///
ObservableList children { get; }
///
/// Display name of the container.
///
string displayName { get; set; }
///
/// Path of the container.
///
string queryPath { get; }
}
///
/// Any widget that implements this will be considered for serialization (only if the setter is set and thus is not read-only)
///
public interface IValueField
{
///
/// Return the value of the field.
///
/// Value of the field.
object GetValue();
///
/// Set the value of the field.
///
/// Input value.
void SetValue(object value);
///
/// Function used to validate the value when setting it.
///
/// Input value.
/// Validated value.
object ValidateValue(object value);
}
// Miscellaneous
///
/// Button widget.
///
public class Button : Widget
{
///
/// Action performed by the button.
///
public Action action { get; set; }
}
///
/// A field that displays a read-only value.
///
public class Value : Widget
{
///
/// Getter for the Value.
///
public Func