A game about forced loneliness, made by TACStudios
at master 144 lines 5.8 kB view raw
1using System; 2using UnityEngine; 3using UnityEngine.UIElements; 4 5namespace UnityEditor.Rendering 6{ 7 /// <summary> UITK component to display header styled foldout</summary> 8 [UxmlElement] 9 public partial class HeaderFoldout : Foldout 10 { 11 const string k_StylesheetPathFormat = "Packages/com.unity.render-pipelines.core/Editor/StyleSheets/HeaderFoldout{0}.uss"; 12 const string k_Class = "header-foldout"; 13 const string k_IconName = "header-foldout__icon"; 14 15 private string m_DocumentationURL; 16 private Texture2D m_Icon; 17 private Func<GenericMenu> m_ContextMenuGenerator; 18 private VisualElement m_HelpButton; 19 private VisualElement m_ContextMenuButton; 20 private VisualElement m_IconElement; 21 22 /// <summary>URL to use on documentation icon. If null, button don't show.</summary> 23 public string documentationURL 24 { 25 get => m_DocumentationURL; 26 set 27 { 28 if (m_DocumentationURL == value) 29 return; 30 31 m_DocumentationURL = value; 32 m_HelpButton?.SetEnabled(!string.IsNullOrEmpty(m_DocumentationURL)); 33 } 34 } 35 36 /// <summary>Context menu to show on click of the context button. If null, button don't show.</summary> 37 public Func<GenericMenu> contextMenuGenerator //Use ImGUI for now 38 { 39 get => m_ContextMenuGenerator; 40 set 41 { 42 if (m_ContextMenuGenerator == value) 43 return; 44 45 m_ContextMenuGenerator = value; 46 m_ContextMenuButton?.SetEnabled(m_ContextMenuGenerator != null); 47 } 48 } 49 50 /// <summary>Optional icon image. If not set, no icon is shown.</summary> 51 public Texture2D icon 52 { 53 get => m_Icon; 54 set 55 { 56 if (m_Icon == value) 57 return; 58 59 m_Icon = value; 60 m_IconElement.style.backgroundImage = Background.FromTexture2D(m_Icon); 61 m_IconElement.style.display = m_Icon != null ? DisplayStyle.Flex : DisplayStyle.None; 62 } 63 } 64 65 /// <summary>Constructor</summary> 66 public HeaderFoldout() : base() 67 { 68 styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(string.Format(k_StylesheetPathFormat, ""))); 69 styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(string.Format(k_StylesheetPathFormat, EditorGUIUtility.isProSkin ? "Dark" : "Light"))); 70 AddToClassList(k_Class); 71 72 RegisterCallback<AttachToPanelEvent>(DelayedInit); 73 74 var line = hierarchy[0][0]; //pass by herarchy to ignore content redirection 75 76 m_HelpButton = new Button(Background.FromTexture2D(CoreEditorStyles.iconHelp), () => Help.BrowseURL(m_DocumentationURL)); 77 m_HelpButton.SetEnabled(!string.IsNullOrEmpty(m_DocumentationURL)); 78 line.Add(m_HelpButton); 79 80 m_ContextMenuButton = new Button(Background.FromTexture2D(CoreEditorStyles.paneOptionsIcon), () => ShowMenu()); 81 m_ContextMenuButton.SetEnabled(m_ContextMenuGenerator != null); 82 line.Add(m_ContextMenuButton); 83 84 m_IconElement = new Image(); 85 m_IconElement.name = k_IconName; 86 m_IconElement.style.display = DisplayStyle.None; // Disable by default, will be enabled if icon is set 87 // Delay insertion of icon to happen after foldout is constructed so we can put it in the right place 88 RegisterCallbackOnce<AttachToPanelEvent>(evt => line.Insert(1, m_IconElement)); 89 } 90 91 void DelayedInit(AttachToPanelEvent evt) 92 { 93 //Only show top line if previous item is not a HeaderFoldout to avoid bolder border 94 bool shouldShowTopLine = true; 95 var parent = hierarchy.parent; 96 int posInParent = parent.hierarchy.IndexOf(this); 97 if (posInParent > 0 && parent[posInParent - 1].ClassListContains(k_Class)) 98 shouldShowTopLine = false; 99 100 style.borderTopWidth = shouldShowTopLine ? 1 : 0; 101 } 102 103 void ShowMenu() 104 { 105 var menu = m_ContextMenuGenerator.Invoke(); 106 menu.DropDown(new Rect(m_ContextMenuButton.worldBound.position + m_ContextMenuButton.worldBound.size.y * Vector2.up, Vector2.zero)); 107 } 108 } 109 110 /// <summary> UITK component to display header styled foldout. This variant have an enable checkbox.</summary> 111 public class HeaderToggleFoldout : HeaderFoldout 112 { 113 private Toggle m_Toggle; 114 115 /// <summary>Property to get the enablement state</summary> 116 public bool enabled 117 { 118 get => m_Toggle.value; 119 set => m_Toggle.value = value; 120 } 121 122 /// <summary>Quick access to the enable toggle if one need to register events</summary> 123 public Toggle enableToggle => m_Toggle; 124 125 /// <summary>Constructor</summary> 126 public HeaderToggleFoldout() : base() 127 { 128 var line = hierarchy[0][0]; //pass by herarchy to ignore content redirection 129 m_Toggle = new Toggle() 130 { 131 value = true, 132 name = "enable-checkbox", 133 }; 134 135 //Need to delay insertion as foldout will be constructed after and we need to squeeze rigth after 136 RegisterCallbackOnce<AttachToPanelEvent>(evt => line.Insert(1, m_Toggle)); 137 138 m_Toggle.RegisterValueChangedCallback(HandleDisabling); 139 } 140 141 void HandleDisabling(ChangeEvent<bool> evt) 142 => contentContainer.SetEnabled(evt.newValue); 143 } 144}