asecli 0.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. asecli/__init__.py +3 -0
  2. asecli/bridge/__init__.py +40 -0
  3. asecli/bridge/_editor_port_contract.py +131 -0
  4. asecli/bridge/_editor_primitives.py +205 -0
  5. asecli/bridge/_editor_spec_grammar.py +245 -0
  6. asecli/bridge/_editor_spec_io.py +26 -0
  7. asecli/bridge/_editor_spec_validation.py +218 -0
  8. asecli/bridge/_gui_handoff_store.py +78 -0
  9. asecli/bridge/_gui_project.py +35 -0
  10. asecli/bridge/_gui_resource_store.py +159 -0
  11. asecli/bridge/_gui_resource_upgrade.py +122 -0
  12. asecli/bridge/editor_create.py +173 -0
  13. asecli/bridge/editor_spec.py +250 -0
  14. asecli/bridge/graph_geometry.py +249 -0
  15. asecli/bridge/graph_geometry_parser.py +57 -0
  16. asecli/bridge/graph_inspect.py +136 -0
  17. asecli/bridge/gui_handoff.py +100 -0
  18. asecli/bridge/gui_presentation.py +70 -0
  19. asecli/bridge/gui_provider_detection.py +197 -0
  20. asecli/bridge/gui_runtime_probe.py +25 -0
  21. asecli/bridge/gui_support.py +240 -0
  22. asecli/bridge/gui_support_resource.py +58 -0
  23. asecli/bridge/mcp_client.py +231 -0
  24. asecli/bridge/recompile.py +107 -0
  25. asecli/bridge/resource_text.py +12 -0
  26. asecli/bridge/resources/asecli_material_gui.authoring.part00.cs.txt +238 -0
  27. asecli/bridge/resources/asecli_material_gui.authoring.part01.cs.txt +235 -0
  28. asecli/bridge/resources/asecli_material_gui.authoring.store.cs.txt +125 -0
  29. asecli/bridge/resources/asecli_material_gui.condition.cs.txt +99 -0
  30. asecli/bridge/resources/asecli_material_gui.hydration.cs.txt +105 -0
  31. asecli/bridge/resources/asecli_material_gui.part00.cs.txt +300 -0
  32. asecli/bridge/resources/asecli_material_gui.part01.cs.txt +290 -0
  33. asecli/bridge/resources/asecli_material_gui.reconciliation.cs.txt +174 -0
  34. asecli/bridge/resources/asecli_material_gui.transaction.cs.txt +108 -0
  35. asecli/bridge/resources/editor_create.part00.cs.txt +176 -0
  36. asecli/bridge/resources/editor_create.part01.cs.txt +145 -0
  37. asecli/bridge/resources/editor_create.part02.cs.txt +139 -0
  38. asecli/bridge/resources/editor_create.part03.cs.txt +161 -0
  39. asecli/bridge/resources/editor_create.part04.cs.txt +114 -0
  40. asecli/bridge/resources/wire_route.transaction.cs.txt +140 -0
  41. asecli/bridge/wire_route.py +127 -0
  42. asecli/checks/__init__.py +10 -0
  43. asecli/checks/checksum.py +53 -0
  44. asecli/checks/local_vars.py +135 -0
  45. asecli/checks/usage.py +141 -0
  46. asecli/checks/validate.py +129 -0
  47. asecli/cli/__init__.py +1 -0
  48. asecli/cli/commands.py +237 -0
  49. asecli/cli/commentary_command.py +158 -0
  50. asecli/cli/create_command.py +250 -0
  51. asecli/cli/custom_gui_command.py +170 -0
  52. asecli/cli/gui_provider.py +30 -0
  53. asecli/cli/gui_support_command.py +35 -0
  54. asecli/cli/io.py +214 -0
  55. asecli/cli/layout_command.py +213 -0
  56. asecli/cli/main.py +245 -0
  57. asecli/cli/recompile_metadata.py +53 -0
  58. asecli/cli/skill_command.py +121 -0
  59. asecli/cli/usage_command.py +42 -0
  60. asecli/core/__init__.py +84 -0
  61. asecli/core/comment_bounds.py +166 -0
  62. asecli/core/comment_layout.py +167 -0
  63. asecli/core/comment_metrics.py +132 -0
  64. asecli/core/comment_purpose.py +140 -0
  65. asecli/core/commentary.py +225 -0
  66. asecli/core/compiled_metadata.py +135 -0
  67. asecli/core/compiled_properties.py +190 -0
  68. asecli/core/custom_gui.py +250 -0
  69. asecli/core/custom_gui_versions.py +35 -0
  70. asecli/core/fishbone_placement.py +159 -0
  71. asecli/core/fishbone_topology.py +186 -0
  72. asecli/core/graph_ops.py +122 -0
  73. asecli/core/layout.py +174 -0
  74. asecli/core/layout_audit.py +237 -0
  75. asecli/core/layout_audit_geometry.py +247 -0
  76. asecli/core/layout_audit_repeated.py +44 -0
  77. asecli/core/layout_graph.py +113 -0
  78. asecli/core/local_vars.py +54 -0
  79. asecli/core/material_gui_condition.py +68 -0
  80. asecli/core/material_gui_protocol.py +35 -0
  81. asecli/core/material_gui_spec.py +191 -0
  82. asecli/core/meticulous_layout.py +114 -0
  83. asecli/core/model.py +237 -0
  84. asecli/core/property_presentation.py +233 -0
  85. asecli/core/wire_geometry.py +83 -0
  86. asecli/core/wire_router.py +248 -0
  87. asecli/schema/__init__.py +49 -0
  88. asecli/schema/data/observed.json +16 -0
  89. asecli/schema/data/schemas.json +14106 -0
  90. asecli/skills/asecli/SKILL.md +275 -0
  91. asecli/skills/asecli/references/layout-standard.md +99 -0
  92. asecli/skills/asecli/references/master-output-settings-standard.md +51 -0
  93. asecli/skills/asecli/references/material-property-standard.md +108 -0
  94. asecli-0.6.2.dist-info/METADATA +594 -0
  95. asecli-0.6.2.dist-info/RECORD +98 -0
  96. asecli-0.6.2.dist-info/WHEEL +4 -0
  97. asecli-0.6.2.dist-info/entry_points.txt +2 -0
  98. asecli-0.6.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,99 @@
1
+
2
+ #if UNITY_EDITOR
3
+ namespace ASECLI.MaterialGUI
4
+ {
5
+ using System;
6
+ using UnityEditor;
7
+ using UnityEngine;
8
+
9
+ internal static class EnableIfMzguiCondition
10
+ {
11
+ internal static bool Matches(
12
+ MaterialProperty property, string sourceName, string comparison, float expected)
13
+ {
14
+ if (property == null || property.targets == null || property.targets.Length == 0)
15
+ return false;
16
+ foreach (UnityEngine.Object target in property.targets)
17
+ {
18
+ Material material = target as Material;
19
+ if (material == null || !material.HasProperty(sourceName) ||
20
+ !Compare(material.GetFloat(sourceName), comparison, expected))
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+
26
+ private static bool Compare(float actual, string comparison, float expected)
27
+ {
28
+ if (comparison == "Less") return actual < expected;
29
+ if (comparison == "LessEqual") return actual <= expected;
30
+ if (comparison == "Equal") return Mathf.Approximately(actual, expected);
31
+ if (comparison == "NotEqual") return !Mathf.Approximately(actual, expected);
32
+ if (comparison == "GreaterEqual") return actual >= expected;
33
+ if (comparison == "Greater") return actual > expected;
34
+ return false;
35
+ }
36
+ }
37
+
38
+ #if ASECLI_FALLBACK_PROVIDER
39
+ public sealed class EnableIfMzguiDrawer : MaterialPropertyDrawer
40
+ {
41
+ private readonly string sourceName;
42
+ private readonly string comparison;
43
+ private readonly float expected;
44
+
45
+ public EnableIfMzguiDrawer(string sourceName, string comparison, float expected)
46
+ {
47
+ this.sourceName = sourceName ?? String.Empty;
48
+ this.comparison = comparison ?? "Equal";
49
+ this.expected = expected;
50
+ }
51
+
52
+ public override float GetPropertyHeight(
53
+ MaterialProperty prop, string label, MaterialEditor editor)
54
+ {
55
+ return MaterialEditor.GetDefaultPropertyHeight(prop);
56
+ }
57
+
58
+ public override void OnGUI(
59
+ Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
60
+ {
61
+ bool enabled = EnableIfMzguiCondition.Matches(
62
+ prop, sourceName, comparison, expected);
63
+ using (new EditorGUI.DisabledScope(!enabled))
64
+ editor.DefaultShaderProperty(position, prop, label.text);
65
+ if (!String.IsNullOrEmpty(label.tooltip))
66
+ {
67
+ Rect tooltipRect = position;
68
+ tooltipRect.width = Mathf.Min(position.width, EditorGUIUtility.labelWidth);
69
+ GUI.Label(
70
+ tooltipRect, new GUIContent(String.Empty, label.tooltip), GUIStyle.none);
71
+ }
72
+ }
73
+ }
74
+ #else
75
+ public sealed class EnableIfMzguiDrawer : MZGUI.MzguiDrawer
76
+ {
77
+ private readonly string sourceName;
78
+ private readonly string comparison;
79
+ private readonly float expected;
80
+
81
+ public EnableIfMzguiDrawer(string sourceName, string comparison, float expected)
82
+ {
83
+ this.sourceName = sourceName ?? String.Empty;
84
+ this.comparison = comparison ?? "Equal";
85
+ this.expected = expected;
86
+ }
87
+
88
+ public override void DrawProp(
89
+ Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
90
+ {
91
+ bool enabled = EnableIfMzguiCondition.Matches(
92
+ prop, sourceName, comparison, expected);
93
+ using (new EditorGUI.DisabledScope(!enabled))
94
+ base.DrawProp(position, prop, label, editor);
95
+ }
96
+ }
97
+ #endif
98
+ }
99
+ #endif
@@ -0,0 +1,105 @@
1
+
2
+ #if UNITY_EDITOR
3
+ namespace ASECLI.MaterialGUI.Authoring
4
+ {
5
+ using System;
6
+ using System.Collections;
7
+ using System.Collections.Generic;
8
+ using System.Reflection;
9
+ using UnityEditor;
10
+ using UnityEngine;
11
+
12
+ // Converts compiled MZGUI metadata into ASE's native Custom Attributes as
13
+ // soon as an unmodified ASE graph opens, so a normal ASE save retains it.
14
+ [InitializeOnLoad]
15
+ internal static class ASEMetadataHydrator
16
+ {
17
+ private static double nextCheck;
18
+
19
+ static ASEMetadataHydrator() { EditorApplication.update += Update; }
20
+
21
+ private static void Update()
22
+ {
23
+ if (EditorApplication.timeSinceStartup < nextCheck) return;
24
+ nextCheck = EditorApplication.timeSinceStartup + 1.0;
25
+ EditorWindow window;
26
+ object graph;
27
+ if (!ASEReflection.TryGraph(out window, out graph)) return;
28
+ Shader shader = ASEReflection.Value(graph, "CurrentShader") as Shader;
29
+ if (shader == null) return;
30
+ Dictionary<string, List<string>> metadata = ReadMetadata(shader);
31
+ if (metadata.Count == 0) return;
32
+ IList nodes = ASEReflection.PropertyNodes(graph);
33
+ if (nodes == null) return;
34
+ bool anyChanged = false;
35
+ foreach (object value in nodes)
36
+ {
37
+ UnityEngine.Object node = value as UnityEngine.Object;
38
+ string propertyName = ASEReflection.Value(
39
+ value, "PropertyName", "m_propertyName") as string;
40
+ List<string> attributes;
41
+ if (node == null || String.IsNullOrEmpty(propertyName) ||
42
+ !metadata.TryGetValue(propertyName, out attributes)) continue;
43
+ bool changed;
44
+ string error;
45
+ if (ASEAttributeStore.TryMergeRaw(node, attributes, out changed, out error))
46
+ anyChanged |= changed;
47
+ }
48
+ if (anyChanged) window.Repaint();
49
+ }
50
+
51
+ private static Dictionary<string, List<string>> ReadMetadata(Shader shader)
52
+ {
53
+ Dictionary<string, List<string>> result =
54
+ new Dictionary<string, List<string>>(StringComparer.Ordinal);
55
+ MethodInfo count = FindShaderUtil("GetPropertyCount", typeof(Shader));
56
+ if (count == null) count = FindShaderUtil("GetShaderPropertyCount", typeof(Shader));
57
+ MethodInfo name = FindShaderUtil("GetPropertyName", typeof(Shader), typeof(int));
58
+ MethodInfo attributes = FindShaderUtil(
59
+ "GetShaderPropertyAttributes", typeof(Shader), typeof(int));
60
+ if (count == null || name == null || attributes == null) return result;
61
+ try
62
+ {
63
+ int length = Convert.ToInt32(count.Invoke(null, new object[] { shader }));
64
+ for (int index = 0; index < length; index++)
65
+ {
66
+ string propertyName = name.Invoke(null, new object[] { shader, index }) as string;
67
+ object raw = attributes.Invoke(null, new object[] { shader, index });
68
+ IEnumerable sequence = raw as IEnumerable;
69
+ if (String.IsNullOrEmpty(propertyName) || sequence == null) continue;
70
+ List<string> managed = new List<string>();
71
+ foreach (object item in sequence)
72
+ {
73
+ string value = item as string ?? String.Empty;
74
+ if (value.StartsWith("FoldoutMzgui", StringComparison.Ordinal) ||
75
+ value.StartsWith("TooltipMzgui", StringComparison.Ordinal) ||
76
+ value.StartsWith("HelpBoxMzgui", StringComparison.Ordinal) ||
77
+ value.StartsWith("EnableIfMzgui", StringComparison.Ordinal) ||
78
+ value.StartsWith("ASECLIFoldout", StringComparison.Ordinal) ||
79
+ value.StartsWith("ASECLITooltip", StringComparison.Ordinal) ||
80
+ value.StartsWith("ASECLIHelpBox", StringComparison.Ordinal) ||
81
+ value.StartsWith("ASECLIEnableIf", StringComparison.Ordinal))
82
+ managed.Add(value);
83
+ }
84
+ if (managed.Count > 0) result[propertyName] = managed;
85
+ }
86
+ }
87
+ catch (Exception exception)
88
+ {
89
+ Debug.LogWarning("ASECLI GUI metadata hydration skipped: " + exception.Message);
90
+ }
91
+ return result;
92
+ }
93
+
94
+ private static MethodInfo FindShaderUtil(string name, params Type[] arguments)
95
+ {
96
+ return typeof(ShaderUtil).GetMethod(
97
+ name,
98
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
99
+ null,
100
+ arguments,
101
+ null);
102
+ }
103
+ }
104
+ }
105
+ #endif
@@ -0,0 +1,300 @@
1
+ #define ASECLI_FALLBACK_PROVIDER
2
+ // ASECLI clean-room implementation of the public MZGUI.MZGUI contract.
3
+ // New shaders use the native FoldoutMzgui, TooltipMzgui and HelpBoxMzgui names.
4
+ #if UNITY_EDITOR
5
+ using System;
6
+ using System.Collections;
7
+ using System.Collections.Generic;
8
+ using System.Globalization;
9
+ using System.IO;
10
+ using System.Reflection;
11
+ using System.Text.RegularExpressions;
12
+ using UnityEditor;
13
+ using UnityEngine;
14
+
15
+ namespace ASECLI.MaterialGUI
16
+ {
17
+ public interface IASECLIFallbackProvider { }
18
+ internal interface IASECLIMetadataDecorator
19
+ {
20
+ string MetadataType { get; }
21
+ string MetadataValue { get; }
22
+ }
23
+
24
+ // These zero-height decorators let Unity retain its normal property/drawer path
25
+ // while ASECLIMaterialGUI interprets their metadata at the ShaderGUI layer.
26
+ public sealed class ASECLIFoldoutDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
27
+ {
28
+ public string MetadataType { get { return "ASECLIFoldout"; } }
29
+ public string MetadataValue { get; private set; }
30
+ public ASECLIFoldoutDecorator() : this(String.Empty) { }
31
+ public ASECLIFoldoutDecorator(string value) { MetadataValue = value ?? String.Empty; }
32
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
33
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
34
+ }
35
+
36
+ public sealed class ASECLITooltipDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
37
+ {
38
+ public string MetadataType { get { return "ASECLITooltip"; } }
39
+ public string MetadataValue { get; private set; }
40
+ public ASECLITooltipDecorator() : this(String.Empty) { }
41
+ public ASECLITooltipDecorator(string value) { MetadataValue = value ?? String.Empty; }
42
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
43
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
44
+ }
45
+
46
+ public sealed class ASECLIHelpBoxDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
47
+ {
48
+ public string MetadataType { get { return "ASECLIHelpBox"; } }
49
+ public string MetadataValue { get; private set; }
50
+ public ASECLIHelpBoxDecorator() : this(String.Empty) { }
51
+ public ASECLIHelpBoxDecorator(string value) { MetadataValue = value ?? String.Empty; }
52
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
53
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
54
+ }
55
+
56
+ // Input-only shims for the historical serialized attributes. They are only
57
+ // needed by the MaterialPropertyHandler fallback when ShaderUtil cannot
58
+ // return raw property attributes; ASECLI never writes these names.
59
+ public sealed class FoldoutMzguiDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
60
+ {
61
+ public string MetadataType { get { return "FoldoutMzgui"; } }
62
+ public string MetadataValue { get; private set; }
63
+ public FoldoutMzguiDecorator() : this(String.Empty) { }
64
+ public FoldoutMzguiDecorator(string value) { MetadataValue = value ?? String.Empty; }
65
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
66
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
67
+ }
68
+
69
+ public sealed class TooltipMzguiDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
70
+ {
71
+ public string MetadataType { get { return "TooltipMzgui"; } }
72
+ public string MetadataValue { get; private set; }
73
+ public TooltipMzguiDecorator() : this(String.Empty) { }
74
+ public TooltipMzguiDecorator(string value) { MetadataValue = value ?? String.Empty; }
75
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
76
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
77
+ }
78
+
79
+ public sealed class HelpBoxMzguiDecorator : MaterialPropertyDrawer, IASECLIMetadataDecorator
80
+ {
81
+ public string MetadataType { get { return "HelpBoxMzgui"; } }
82
+ public string MetadataValue { get; private set; }
83
+ public HelpBoxMzguiDecorator() : this(String.Empty) { }
84
+ public HelpBoxMzguiDecorator(string value) { MetadataValue = value ?? String.Empty; }
85
+ public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) { return 0f; }
86
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { }
87
+ }
88
+
89
+ public class ASECLIMaterialGUI : ShaderGUI, IASECLIFallbackProvider
90
+ {
91
+ private sealed class PropertyMetadata
92
+ {
93
+ public string Foldout = String.Empty;
94
+ public string Tooltip = String.Empty;
95
+ public string Help = String.Empty;
96
+ }
97
+
98
+ private static readonly Regex CustomUnicodePattern =
99
+ new Regex("#([0-9A-Fa-f]{4})", RegexOptions.Compiled);
100
+ private static readonly Regex RawPropertyAttributePattern =
101
+ new Regex("\\[(?<attribute>[^\\]\\r\\n]*)\\]", RegexOptions.Compiled);
102
+ private static bool metadataWarningLogged;
103
+
104
+ // ShaderGUI instances can be recreated between IMGUI Layout and Repaint
105
+ // passes. Foldout state therefore must outlive one inspector instance,
106
+ // otherwise a click changes the arrow but leaves the previous layout.
107
+ private static readonly Dictionary<string, bool> foldoutStates =
108
+ new Dictionary<string, bool>(StringComparer.Ordinal);
109
+ private Shader cachedShader;
110
+ private Hash128 cachedDependencyHash;
111
+ private bool hasCachedDependencyHash;
112
+ private Dictionary<string, PropertyMetadata> cachedMetadata;
113
+ private Dictionary<string, string> cachedDefaultValues;
114
+
115
+ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
116
+ {
117
+ Material material = materialEditor != null ? materialEditor.target as Material : null;
118
+ Shader shader = material != null ? material.shader : null;
119
+ if (materialEditor == null || shader == null || properties == null)
120
+ {
121
+ base.OnGUI(materialEditor, properties);
122
+ return;
123
+ }
124
+
125
+ EnsureCache(shader);
126
+ bool insideFoldout = false;
127
+ bool currentFoldoutOpen = true;
128
+
129
+ foreach (MaterialProperty property in properties)
130
+ {
131
+ PropertyMetadata metadata;
132
+ if (!cachedMetadata.TryGetValue(property.name, out metadata))
133
+ metadata = new PropertyMetadata();
134
+
135
+ if (!String.IsNullOrEmpty(metadata.Foldout))
136
+ {
137
+ insideFoldout = true;
138
+ currentFoldoutOpen = DrawFoldout(
139
+ shader,
140
+ property,
141
+ metadata.Foldout,
142
+ materialEditor
143
+ );
144
+ }
145
+
146
+ if (insideFoldout && !currentFoldoutOpen)
147
+ continue;
148
+ if ((property.flags & MaterialProperty.PropFlags.HideInInspector) != 0)
149
+ continue;
150
+
151
+ string defaultValue;
152
+ if (!cachedDefaultValues.TryGetValue(property.name, out defaultValue))
153
+ defaultValue = "Unknown";
154
+ GUIContent label = new GUIContent(
155
+ property.displayName,
156
+ BuildTooltip(metadata.Tooltip, property.name, defaultValue)
157
+ );
158
+ DrawProperty(materialEditor, property, label);
159
+
160
+ if (!String.IsNullOrEmpty(metadata.Help))
161
+ DrawInlineHelp(metadata.Help);
162
+ }
163
+
164
+ EditorGUILayout.Space();
165
+ materialEditor.RenderQueueField();
166
+ materialEditor.EnableInstancingField();
167
+ materialEditor.DoubleSidedGIField();
168
+ }
169
+
170
+ private static void DrawProperty(
171
+ MaterialEditor materialEditor,
172
+ MaterialProperty property,
173
+ GUIContent label)
174
+ {
175
+ if (ShouldWrapPropertyLabel(label))
176
+ {
177
+ DrawWrappedProperty(materialEditor, property, label);
178
+ return;
179
+ }
180
+
181
+ float height = materialEditor.GetPropertyHeight(property, label.text);
182
+ Rect position = EditorGUILayout.GetControlRect(true, height);
183
+ materialEditor.ShaderProperty(position, property, label);
184
+ }
185
+
186
+ private static bool ShouldWrapPropertyLabel(GUIContent label)
187
+ {
188
+ float availableWidth = Mathf.Max(
189
+ 80f,
190
+ (EditorGUIUtility.currentViewWidth * 0.45f) -
191
+ 24f - (EditorGUI.indentLevel * 15f)
192
+ );
193
+ return EditorStyles.label.CalcSize(label).x > availableWidth;
194
+ }
195
+
196
+ private static void DrawWrappedProperty(
197
+ MaterialEditor materialEditor,
198
+ MaterialProperty property,
199
+ GUIContent label)
200
+ {
201
+ GUIStyle wrappedLabel = new GUIStyle(EditorStyles.label);
202
+ wrappedLabel.wordWrap = true;
203
+ float labelWidth = Mathf.Max(
204
+ 1f,
205
+ EditorGUIUtility.currentViewWidth - 40f -
206
+ (EditorGUI.indentLevel * 15f)
207
+ );
208
+ float labelHeight = wrappedLabel.CalcHeight(label, labelWidth);
209
+ Rect labelPosition = EditorGUI.IndentedRect(
210
+ EditorGUILayout.GetControlRect(false, labelHeight)
211
+ );
212
+ EditorGUI.LabelField(labelPosition, label, wrappedLabel);
213
+
214
+ float height = materialEditor.GetPropertyHeight(property, String.Empty);
215
+ Rect position = EditorGUILayout.GetControlRect(true, height);
216
+ materialEditor.ShaderProperty(position, property, GUIContent.none);
217
+ }
218
+
219
+ private static void DrawInlineHelp(string text)
220
+ {
221
+ GUIContent content = new GUIContent(text);
222
+ GUIStyle style = new GUIStyle(EditorStyles.miniLabel);
223
+ style.fontStyle = FontStyle.Italic;
224
+ style.wordWrap = true;
225
+
226
+ float textWidth = Mathf.Max(
227
+ 1f,
228
+ EditorGUIUtility.currentViewWidth - 64f - (EditorGUI.indentLevel * 15f)
229
+ );
230
+ float textHeight = style.CalcHeight(content, textWidth);
231
+ Rect row = EditorGUI.IndentedRect(
232
+ EditorGUILayout.GetControlRect(false, textHeight + 8f)
233
+ );
234
+
235
+ Rect backgroundRect = new Rect(row.x, row.y - 2f, row.width, row.height + 4f);
236
+ EditorGUI.DrawRect(backgroundRect, new Color(0f, 0f, 0f, 0.1f));
237
+
238
+ Rect accentRect = new Rect(
239
+ backgroundRect.x + 6f,
240
+ backgroundRect.y + 6f,
241
+ 3f,
242
+ Mathf.Max(1f, backgroundRect.height - 12f)
243
+ );
244
+ EditorGUI.DrawRect(accentRect, new Color(1f, 1f, 1f, 0.3f));
245
+
246
+ Rect textRect = new Rect(
247
+ row.x + 16f,
248
+ row.y + 4f,
249
+ Mathf.Max(1f, row.width - 32f),
250
+ textHeight
251
+ );
252
+ Color previousColor = GUI.color;
253
+ GUI.color = EditorGUIUtility.isProSkin
254
+ ? new Color(1f, 1f, 1f, 0.4f)
255
+ : new Color(0f, 0f, 0f, 0.55f);
256
+ GUI.Label(textRect, content, style);
257
+ GUI.color = previousColor;
258
+ EditorGUILayout.Space(2f);
259
+ }
260
+
261
+ private bool DrawFoldout(
262
+ Shader shader,
263
+ MaterialProperty property,
264
+ string title,
265
+ MaterialEditor materialEditor)
266
+ {
267
+ string key = shader.name + "\n" + property.name;
268
+ bool state;
269
+ if (!foldoutStates.TryGetValue(key, out state))
270
+ state = true;
271
+ bool previousState = state;
272
+ #if UNITY_2019_3_OR_NEWER
273
+ state = EditorGUILayout.Foldout(state, title, true, EditorStyles.foldoutHeader);
274
+ #else
275
+ state = EditorGUILayout.Foldout(state, title, true);
276
+ #endif
277
+ foldoutStates[key] = state;
278
+ if (state != previousState && materialEditor != null)
279
+ materialEditor.Repaint();
280
+ return state;
281
+ }
282
+
283
+ private void EnsureCache(Shader shader)
284
+ {
285
+ string assetPath = AssetDatabase.GetAssetPath(shader);
286
+ bool hasDependencyHash = !String.IsNullOrEmpty(assetPath);
287
+ Hash128 dependencyHash = hasDependencyHash
288
+ ? AssetDatabase.GetAssetDependencyHash(assetPath)
289
+ : default(Hash128);
290
+ bool cacheIsCurrent = cachedShader == shader &&
291
+ cachedMetadata != null && cachedDefaultValues != null &&
292
+ (!hasDependencyHash || (hasCachedDependencyHash && dependencyHash == cachedDependencyHash));
293
+ if (cacheIsCurrent)
294
+ return;
295
+ cachedShader = shader;
296
+ cachedDependencyHash = dependencyHash;
297
+ hasCachedDependencyHash = hasDependencyHash;
298
+ cachedMetadata = ReadMetadata(shader);
299
+ cachedDefaultValues = ReadDefaultValues(shader);
300
+ }