123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor.UIElements;
- using UnityEngine;
- using UnityEngine.UIElements;
- namespace UnityEditor.Rendering.LookDev
- {
- partial class DisplayWindow
- {
- static partial class Style
- {
- internal const string k_DebugViewLabel = "Selected View";
- internal const string k_DebugShadowLabel = "Display Shadows";
- internal const string k_DebugViewMode = "View Mode";
- internal static readonly Texture2D k_LockOpen = CoreEditorUtils.LoadIcon(Style.k_IconFolder, "Unlocked", forceLowRes: true);
- internal static readonly Texture2D k_LockClose = CoreEditorUtils.LoadIcon(Style.k_IconFolder, "Locked", forceLowRes: true);
- // /!\ WARNING:
- //The following const are used in the uss.
- //If you change them, update the uss file too.
- internal const string k_DebugToolbarName = "debugToolbar";
- }
- MultipleSourceToggle m_Shadow;
- MultipleSourcePopupField m_DebugView;
- List<string> listDebugMode;
- bool cameraSynced
- => LookDev.currentContext.cameraSynced;
- ViewContext lastFocusedViewContext
- => LookDev.currentContext.GetViewContent(LookDev.currentContext.layout.lastFocusedView);
- TargetDebugView targetDebugView
- {
- get => layout.debugPanelSource;
- set
- {
- if (layout.debugPanelSource != value)
- {
- layout.debugPanelSource = value;
- UpdateSideDebugPanelProperties();
- }
- }
- }
- bool debugView1SidePanel
- => targetDebugView == TargetDebugView.First
- || targetDebugView == TargetDebugView.Both;
- bool debugView2SidePanel
- => targetDebugView == TargetDebugView.Second
- || targetDebugView == TargetDebugView.Both;
- void ApplyInFilteredViewsContext(Action<ViewContext> action)
- {
- if (debugView1SidePanel)
- action.Invoke(LookDev.currentContext.GetViewContent(ViewIndex.First));
- if (debugView2SidePanel)
- action.Invoke(LookDev.currentContext.GetViewContent(ViewIndex.Second));
- }
- T GetInFilteredViewsContext<T>(Func<ViewContext, T> getter, out bool multipleDifferentValue)
- {
- T res1 = default;
- T res2 = default;
- multipleDifferentValue = false;
- bool view1 = debugView1SidePanel;
- bool view2 = debugView2SidePanel;
-
- if (view1)
- res1 = getter.Invoke(LookDev.currentContext.GetViewContent(ViewIndex.First));
- if (view2)
- res2 = getter.Invoke(LookDev.currentContext.GetViewContent(ViewIndex.Second));
- if (view1 && view2 && !res1.Equals(res2))
- {
- multipleDifferentValue = true;
- return default;
- }
- else
- return view1 ? res1 : res2;
- }
- void ReadValueFromSourcesWithoutNotify<T, K>(K element, Func<ViewContext, T> from)
- where K : BaseField<T>, IMultipleSource
- {
- bool multipleDifferentValue;
- T newValue = GetInFilteredViewsContext(from, out multipleDifferentValue);
- if (element is MultipleSourcePopupField)
- element.inMultipleValueState = multipleDifferentValue;
- element.SetValueWithoutNotify(newValue);
- element.inMultipleValueState = multipleDifferentValue;
- }
- #region Hack_Support_UIElement_MixedValueState
- class MultipleDifferentValue : TextElement
- {
- public new class UxmlFactory : UxmlFactory<MultipleDifferentValue, UxmlTraits> { }
- public new class UxmlTraits : TextElement.UxmlTraits { }
- public new static readonly string ussClassName = "unity-multipledifferentevalue";
-
- public MultipleDifferentValue()
- {
- AddToClassList(ussClassName);
- text = "-";
- }
- }
- interface IMultipleSource
- {
- bool inMultipleValueState { get; set; }
- }
- class MultipleSourceToggle : Toggle, IMultipleSource
- {
- MultipleDifferentValue m_MultipleOverlay;
- bool m_InMultipleValueState = false;
- public bool inMultipleValueState
- {
- get => m_InMultipleValueState;
- set
- {
- if (value != m_InMultipleValueState)
- {
- m_MultipleOverlay.style.display = value ? DisplayStyle.Flex : DisplayStyle.None;
- m_InMultipleValueState = value;
- }
- }
- }
- public MultipleSourceToggle() : base ()
- {
- m_MultipleOverlay = new MultipleDifferentValue();
- this.Q(name: "unity-checkmark").Add(m_MultipleOverlay);
- m_MultipleOverlay.style.display = DisplayStyle.None;
- }
- public MultipleSourceToggle(string label) : base(label)
- {
- m_MultipleOverlay = new MultipleDifferentValue();
- this.Q(name: "unity-checkmark").Add(m_MultipleOverlay);
- m_MultipleOverlay.style.display = DisplayStyle.None;
- }
- public override void SetValueWithoutNotify(bool newValue)
- {
- if (inMultipleValueState)
- inMultipleValueState = false;
- base.SetValueWithoutNotify(newValue);
- }
- public override bool value
- {
- get => inMultipleValueState ? default : base.value;
- set
- {
- if (inMultipleValueState)
- inMultipleValueState = false;
- base.value = value;
- }
- }
- }
- class MultipleSourcePopupField : PopupField<string>, IMultipleSource
- {
- internal readonly int count;
- MultipleDifferentValue m_MultipleOverlay;
- bool m_InMultipleValueState = false;
- public bool inMultipleValueState
- {
- get => m_InMultipleValueState;
- set
- {
- if (value != m_InMultipleValueState)
- {
- m_MultipleOverlay.style.display = value ? DisplayStyle.Flex : DisplayStyle.None;
- m_InMultipleValueState = value;
- }
- }
- }
- public MultipleSourcePopupField(string label, List<string> choices, int defaultIndex = 0)
- : base(
- label,
- choices,
- defaultIndex,
- null,
- null)
- {
- count = choices.Count;
- m_MultipleOverlay = new MultipleDifferentValue();
- Add(m_MultipleOverlay);
- m_MultipleOverlay.style.display = DisplayStyle.None;
- }
- public override void SetValueWithoutNotify(string newValue)
- {
- // forbid change from not direct selection as it can be find different value at opening
- if (!inMultipleValueState)
- base.SetValueWithoutNotify(newValue);
- }
- public override string value
- {
- get => inMultipleValueState ? default : base.value;
- set
- {
- //when actively changing in the drop down, quit mixed value state
- if (inMultipleValueState)
- inMultipleValueState = false;
- base.value = value;
- }
- }
- }
- #endregion
- void CreateDebug()
- {
- if (m_MainContainer == null || m_MainContainer.Equals(null))
- throw new System.MemberAccessException("m_MainContainer should be assigned prior CreateEnvironment()");
- m_DebugContainer = new VisualElement() { name = Style.k_DebugContainerName };
- m_MainContainer.Add(m_DebugContainer);
- if (sidePanel == SidePanel.Debug)
- m_MainContainer.AddToClassList(Style.k_ShowDebugPanelClass);
- AddDebugViewSelector();
-
- AddDebugShadow();
- AddDebugViewMode();
- //[TODO: finish]
- //Toggle greyBalls = new Toggle("Grey balls");
- //greyBalls.SetValueWithoutNotify(LookDev.currentContext.GetViewContent(LookDev.currentContext.layout.lastFocusedView).debug.greyBalls);
- //greyBalls.RegisterValueChangedCallback(evt =>
- //{
- // LookDev.currentContext.GetViewContent(LookDev.currentContext.layout.lastFocusedView).debug.greyBalls = evt.newValue;
- //});
- //m_DebugContainer.Add(greyBalls);
- //[TODO: debug why list sometimes empty on resource reloading]
- //[TODO: display only per view]
-
- if (sidePanel == SidePanel.Debug)
- UpdateSideDebugPanelProperties();
- }
- void AddDebugViewSelector()
- {
- ToolbarRadio viewSelector = new ToolbarRadio()
- {
- name = Style.k_DebugToolbarName
- };
- viewSelector.AddRadios(new[]
- {
- Style.k_Camera1Icon,
- Style.k_LinkIcon,
- Style.k_Camera2Icon
- });
- viewSelector.SetValueWithoutNotify((int)targetDebugView);
- viewSelector.RegisterValueChangedCallback(evt
- => targetDebugView = (TargetDebugView)evt.newValue);
- m_DebugContainer.Add(viewSelector);
- }
- void AddDebugShadow()
- {
- m_Shadow = new MultipleSourceToggle(Style.k_DebugShadowLabel);
- ReadValueFromSourcesWithoutNotify(m_Shadow, view => view.debug.shadow);
- m_Shadow.RegisterValueChangedCallback(evt
- => ApplyInFilteredViewsContext(view => view.debug.shadow = evt.newValue));
- m_DebugContainer.Add(m_Shadow);
- }
- void AddDebugViewMode(int pos = -1)
- {
- //if debugPanel is open on script reload, at this time
- //RenderPipelineManager.currentPipeline is still null.
- //So compute the list on next frame only.
- if (LookDev.dataProvider == null)
- {
- EditorApplication.delayCall += () => AddDebugViewMode(2); //2 = hardcoded position of this field
- return;
- }
- if (m_DebugView != null && m_DebugContainer.Contains(m_DebugView))
- m_DebugContainer.Remove(m_DebugView);
- listDebugMode = new List<string>(LookDev.dataProvider?.supportedDebugModes ?? Enumerable.Empty<string>());
- listDebugMode.Insert(0, "None");
- m_DebugView = new MultipleSourcePopupField(Style.k_DebugViewMode, listDebugMode);
- if (sidePanel == SidePanel.Debug)
- ReadValueFromSourcesWithoutNotify(m_DebugView, view => listDebugMode[view.debug.viewMode + 1]);
- m_DebugView.RegisterValueChangedCallback(evt
- => ApplyInFilteredViewsContext(view => view.debug.viewMode = listDebugMode.IndexOf(evt.newValue) - 1));
- if (pos == -1)
- m_DebugContainer.Add(m_DebugView);
- else
- m_DebugContainer.Insert(pos, m_DebugView);
- }
-
- void UpdateSideDebugPanelProperties()
- {
- ReadValueFromSourcesWithoutNotify(m_Shadow, view => view.debug.shadow);
- if (m_DebugView != null)
- ReadValueFromSourcesWithoutNotify(m_DebugView, view => listDebugMode[view.debug.viewMode + 1]);
- }
- }
- }
|