A game about forced loneliness, made by TACStudios
1using System;
2using System.Linq;
3using UnityEngine;
4using UnityEngine.UIElements;
5using UnityEditor.UIElements;
6using UnityEditor.Graphing;
7
8namespace UnityEditor.ShaderGraph.Drawing
9{
10 [Serializable]
11 public enum HlslSourceType { File, String };
12
13 internal class HlslFunctionView : VisualElement
14 {
15 private EnumField m_Type;
16 private TextField m_FunctionName;
17 private ObjectField m_FunctionSource;
18 private Toggle m_FunctionSourceUsePragmas;
19 private TextField m_FunctionBody;
20
21 internal HlslFunctionView(CustomFunctionNode node)
22 {
23 styleSheets.Add(Resources.Load<StyleSheet>("Styles/HlslFunctionView"));
24 Draw(node);
25 }
26
27 private void Draw(CustomFunctionNode node)
28 {
29 var currentControls = this.Children().ToArray();
30 for (int i = 0; i < currentControls.Length; i++)
31 currentControls[i].RemoveFromHierarchy();
32
33 m_Type = new EnumField(node.sourceType);
34 m_Type.RegisterValueChangedCallback(s =>
35 {
36 if ((HlslSourceType)s.newValue != node.sourceType)
37 {
38 node.owner.owner.RegisterCompleteObjectUndo("Change Function Type");
39 node.sourceType = (HlslSourceType)s.newValue;
40 Draw(node);
41 node.owner.ClearErrorsForNode(node);
42 node.ValidateNode();
43 node.Dirty(ModificationScope.Graph);
44 }
45 });
46
47 m_FunctionName = new TextField { value = node.functionName, multiline = false };
48 m_FunctionName.RegisterCallback<FocusInEvent>(s =>
49 {
50 if (m_FunctionName.value == CustomFunctionNode.defaultFunctionName)
51 m_FunctionName.value = "";
52 });
53 m_FunctionName.RegisterCallback<FocusOutEvent>(s =>
54 {
55 if (m_FunctionName.value == "")
56 m_FunctionName.value = CustomFunctionNode.defaultFunctionName;
57 else
58 m_FunctionName.value = NodeUtils.ConvertToValidHLSLIdentifier(m_FunctionName.value);
59
60 if (m_FunctionName.value != node.functionName)
61 {
62 node.owner.owner.RegisterCompleteObjectUndo("Change Function Name");
63 node.functionName = m_FunctionName.value;
64 node.ValidateNode();
65 node.Dirty(ModificationScope.Graph);
66 }
67 });
68
69 string path = AssetDatabase.GUIDToAssetPath(node.functionSource);
70 m_FunctionSource = new ObjectField() { value = AssetDatabase.LoadAssetAtPath<ShaderInclude>(path), objectType = typeof(ShaderInclude) };
71 m_FunctionSource.RegisterValueChangedCallback(s =>
72 {
73 long localId;
74 string guidString = string.Empty;
75 if (s.newValue != null)
76 {
77 AssetDatabase.TryGetGUIDAndLocalFileIdentifier((ShaderInclude)s.newValue, out guidString, out localId);
78 }
79
80 if (guidString != node.functionSource)
81 {
82 node.owner.owner.RegisterCompleteObjectUndo("Change Function Source");
83 node.functionSource = guidString;
84 node.ValidateNode();
85 node.Dirty(ModificationScope.Graph);
86 }
87 });
88
89 m_FunctionSourceUsePragmas = new Toggle
90 {
91 value = node.functionSourceUsePragmas
92 };
93 m_FunctionSourceUsePragmas.RegisterValueChangedCallback(s =>
94 {
95 if (s.newValue != node.functionSourceUsePragmas)
96 {
97 node.owner.owner.RegisterCompleteObjectUndo("Change Function Source Pragma Usage");
98 node.functionSourceUsePragmas = s.newValue;
99 node.ValidateNode();
100 node.Dirty(ModificationScope.Graph);
101 }
102 });
103
104 m_FunctionBody = new TextField { value = node.functionBody, multiline = true };
105 m_FunctionBody.AddToClassList("sg-hlsl-function-view__body");
106 m_FunctionBody.verticalScrollerVisibility = ScrollerVisibility.Auto;
107
108 var functionBodyScrollView = m_FunctionBody.Q<ScrollView>();
109 functionBodyScrollView.mode = ScrollViewMode.VerticalAndHorizontal;
110 functionBodyScrollView.horizontalScrollerVisibility = ScrollerVisibility.Auto;
111
112 m_FunctionBody.RegisterCallback<FocusInEvent>(s =>
113 {
114 if (m_FunctionBody.value == CustomFunctionNode.defaultFunctionBody)
115 m_FunctionBody.value = "";
116 });
117 m_FunctionBody.RegisterCallback<FocusOutEvent>(s =>
118 {
119 if (m_FunctionBody.value == "")
120 m_FunctionBody.value = CustomFunctionNode.defaultFunctionBody;
121
122 if (m_FunctionBody.value != node.functionBody)
123 {
124 node.owner.owner.RegisterCompleteObjectUndo("Change Function Body");
125 node.functionBody = m_FunctionBody.value;
126 node.ValidateNode();
127 node.Dirty(ModificationScope.Graph);
128 }
129 });
130
131 VisualElement typeRow = new VisualElement() { name = "Row" };
132 {
133 typeRow.Add(new Label("Type"));
134 typeRow.Add(m_Type);
135 }
136 Add(typeRow);
137 VisualElement nameRow = new VisualElement() { name = "Row" };
138 {
139 nameRow.Add(new Label("Name"));
140 nameRow.Add(m_FunctionName);
141 }
142 Add(nameRow);
143 switch (node.sourceType)
144 {
145 case HlslSourceType.File:
146 VisualElement sourceRow = new VisualElement() { name = "Row" };
147 {
148 sourceRow.Add(new Label("Source"));
149 sourceRow.Add(m_FunctionSource);
150 }
151 Add(sourceRow);
152
153 VisualElement functionSourceUsePragmasRow = new VisualElement() { name = "Row" };
154 {
155 functionSourceUsePragmasRow.Add(new Label("Use Pragmas"));
156 functionSourceUsePragmasRow.Add(m_FunctionSourceUsePragmas);
157 functionSourceUsePragmasRow.tooltip = "Determines whether or not Unity pragmas from the included file will be used in the generated shader.";
158 }
159 Add(functionSourceUsePragmasRow);
160
161 break;
162 case HlslSourceType.String:
163 VisualElement bodyRow = new VisualElement() { name = "Row" };
164 {
165 bodyRow.Add(new Label("Body"));
166 bodyRow.style.height = 200;
167 bodyRow.Add(m_FunctionBody);
168 }
169 Add(bodyRow);
170 break;
171 }
172 }
173 }
174}