123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- using System;
- using System.Linq;
- using UnityEngine.Assertions;
-
- namespace UnityEngine.Rendering
- {
- /// <summary>
- /// Debug UI Class
- /// </summary>
- public partial class DebugUI
- {
- /// <summary>
- /// A column of checkboxes for enabling and disabling flags.
- /// </summary>
- [Flags]
- public enum Flags
- {
- /// <summary>
- /// None.
- /// </summary>
- None = 0,
- /// <summary>
- /// This widget is Editor only.
- /// </summary>
- EditorOnly = 1 << 1,
- /// <summary>
- /// This widget is Runtime only.
- /// </summary>
- RuntimeOnly = 1 << 2,
- /// <summary>
- /// This widget will force the Debug Editor Window refresh.
- /// </summary>
- EditorForceUpdate = 1 << 3,
- /// <summary>
- /// This widget will appear in the section "Frequently Used"
- /// </summary>
- FrequentlyUsed = 1 << 4
-
- }
-
- /// <summary>
- /// Base class for all debug UI widgets.
- /// </summary>
- public abstract class Widget
- {
- // Set to null until it's added to a panel, be careful
- /// <summary>
- /// Panels containing the widget.
- /// </summary>
- protected Panel m_Panel;
-
- /// <summary>
- /// Panels containing the widget.
- /// </summary>
- public virtual Panel panel
- {
- get { return m_Panel; }
- internal set { m_Panel = value; }
- }
-
- /// <summary>
- /// Parent container.
- /// </summary>
- protected IContainer m_Parent;
-
- /// <summary>
- /// Parent container.
- /// </summary>
- public virtual IContainer parent
- {
- get { return m_Parent; }
- internal set { m_Parent = value; }
- }
-
- /// <summary>
- /// Flags for the widget.
- /// </summary>
- public Flags flags { get; set; }
-
- /// <summary>
- /// Display name.
- /// </summary>
- public string displayName { get; set; }
-
- /// <summary>
- /// Tooltip.
- /// </summary>
- public string tooltip { get; set; }
-
- /// <summary>
- /// Path of the widget.
- /// </summary>
- public string queryPath { get; private set; }
-
- /// <summary>
- /// True if the widget is Editor only.
- /// </summary>
- public bool isEditorOnly => flags.HasFlag(Flags.EditorOnly);
-
- /// <summary>
- /// True if the widget is Runtime only.
- /// </summary>
- public bool isRuntimeOnly => flags.HasFlag(Flags.RuntimeOnly);
-
- /// <summary>
- /// True if the widget is inactive in the editor (i.e. widget is runtime only and the application is not 'Playing').
- /// </summary>
- public bool isInactiveInEditor => (isRuntimeOnly && !Application.isPlaying);
-
- /// <summary>
- /// Optional delegate that can be used to conditionally hide widgets at runtime (e.g. due to state of other widgets).
- /// </summary>
- public Func<bool> isHiddenCallback;
-
- /// <summary>
- /// If <see cref="isHiddenCallback">shouldHideDelegate</see> has been set and returns true, the widget is hidden from the UI.
- /// </summary>
- public bool isHidden => isHiddenCallback?.Invoke() ?? false;
-
- internal virtual void GenerateQueryPath()
- {
- queryPath = displayName.Trim();
-
- if (m_Parent != null)
- queryPath = m_Parent.queryPath + " -> " + queryPath;
- }
-
- /// <summary>
- /// Returns the hash code of the widget.
- /// </summary>
- /// <returns>The hash code of the widget.</returns>
- public override int GetHashCode()
- {
- return queryPath.GetHashCode() ^ isHidden.GetHashCode();
- }
-
- /// <summary>
- /// Helper struct to allow more compact initialization of widgets.
- /// </summary>
- public struct NameAndTooltip
- {
- /// <summary>
- /// The name
- /// </summary>
- public string name;
- /// <summary>
- /// The tooltip
- /// </summary>
- public string tooltip;
- }
-
- /// <summary>
- /// Helper setter to allow more compact initialization of widgets.
- /// </summary>
- public NameAndTooltip nameAndTooltip
- {
- set
- {
- displayName = value.name;
- tooltip = value.tooltip;
- }
- }
- }
-
- /// <summary>
- /// Interface for widgets that can contain other widgets.
- /// </summary>
- public interface IContainer
- {
- /// <summary>
- /// List of children of the container.
- /// </summary>
- ObservableList<Widget> children { get; }
-
- /// <summary>
- /// Display name of the container.
- /// </summary>
- string displayName { get; set; }
-
- /// <summary>
- /// Path of the container.
- /// </summary>
- string queryPath { get; }
- }
-
- /// <summary>
- /// Any widget that implements this will be considered for serialization (only if the setter is set and thus is not read-only)
- /// </summary>
- public interface IValueField
- {
- /// <summary>
- /// Return the value of the field.
- /// </summary>
- /// <returns>Value of the field.</returns>
- object GetValue();
-
- /// <summary>
- /// Set the value of the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- void SetValue(object value);
-
- /// <summary>
- /// Function used to validate the value when setting it.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- object ValidateValue(object value);
- }
-
- // Miscellaneous
- /// <summary>
- /// Button widget.
- /// </summary>
- public class Button : Widget
- {
- /// <summary>
- /// Action performed by the button.
- /// </summary>
- public Action action { get; set; }
- }
-
- /// <summary>
- /// A field that displays a read-only value.
- /// </summary>
- public class Value : Widget
- {
- /// <summary>
- /// Getter for the Value.
- /// </summary>
- public Func<object> getter { get; set; }
-
- /// <summary>
- /// Refresh rate for the read-only value (runtime only)
- /// </summary>
- public float refreshRate = 0.1f;
-
- /// <summary>
- /// Optional C# numeric format string, using following syntax: "{0[:numericFormatString]}"
- /// See https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings
- /// and https://docs.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting
- /// Example: 123.45678 with formatString "{0:F2} ms" --> "123.45 ms".
- /// </summary>
- public string formatString = null;
-
- /// <summary>
- /// Constructor.
- /// </summary>
- public Value()
- {
- displayName = "";
- }
-
- /// <summary>
- /// Returns the value of the widget.
- /// </summary>
- /// <returns>The value of the widget.</returns>
- public virtual object GetValue()
- {
- Assert.IsNotNull(getter);
- return getter();
- }
-
- /// <summary>
- /// Returns the formatted value string for display purposes.
- /// </summary>
- /// <param name="value">Value to be formatted.</param>
- /// <returns>The formatted value string.</returns>
- public virtual string FormatString(object value)
- {
- return string.IsNullOrEmpty(formatString) ? $"{value}" : string.Format(formatString, value);
- }
- }
-
- /// <summary>
- /// A progress bar that displays values between 0% and 100%.
- /// </summary>
- public class ProgressBarValue : Value
- {
- /// <summary>
- /// Minimum value.
- /// </summary>
- public float min = 0f;
- /// <summary>
- /// Maximum value.
- /// </summary>
- public float max = 1f;
-
- /// <summary>
- /// Get the current progress string, remapped to [0, 1] range, representing the progress between min and max.
- /// </summary>
- /// <param name="value">Value to be formatted.</param>
- /// <returns>Formatted progress percentage string between 0% and 100%.</returns>
- public override string FormatString(object value)
- {
- static float Remap01(float v, float x0, float y0) => (v - x0) / (y0 - x0);
-
- float clamped = Mathf.Clamp((float)value, min, max);
- float percentage = Remap01(clamped, min, max);
- return $"{percentage:P1}";
- }
- }
-
- /// <summary>
- /// An array of read-only values that Unity displays in a horizontal row.
- /// </summary>
- public class ValueTuple : Widget
- {
- /// <summary>
- /// Number of elements in the tuple.
- /// </summary>
- public int numElements
- {
- get
- {
- Assert.IsTrue(values.Length > 0);
- return values.Length;
- }
- }
-
- /// <summary>
- /// Value widgets.
- /// </summary>
- public Value[] values;
-
- /// <summary>
- /// Refresh rate for the read-only values (runtime only)
- /// </summary>
- public float refreshRate => values.FirstOrDefault()?.refreshRate ?? 0.1f;
-
- /// <summary>
- /// The currently pinned element index, or -1 if none are pinned.
- /// </summary>
- public int pinnedElementIndex = -1;
- }
- }
- }
|