com.wallstop-studios.unity-helpers 2.0.0-rc73.14 → 2.0.0-rc73.15
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.
- package/Editor/AnimationEventEditor.cs +4 -5
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +1 -1
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +590 -0
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs.meta +3 -0
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +298 -0
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs.meta +3 -0
- package/Editor/FitTextureSizeWindow.cs +5 -44
- package/Editor/PersistentDirectorySettings.cs +248 -0
- package/Editor/PersistentDirectorySettings.cs.meta +3 -0
- package/Editor/PrefabChecker.cs +1 -2
- package/Editor/{AnimationCopier.cs → Sprites/AnimationCopier.cs} +33 -166
- package/Editor/{AnimationCreator.cs → Sprites/AnimationCreator.cs} +9 -80
- package/Editor/Sprites/ScriptableSpriteAtlas.cs +95 -0
- package/Editor/Sprites/ScriptableSpriteAtlas.cs.meta +3 -0
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +938 -0
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs.meta +3 -0
- package/Editor/{SpriteCropper.cs → Sprites/SpriteCropper.cs} +66 -64
- package/Editor/{SpriteSettingsApplier.cs → Sprites/SpriteSettingsApplier.cs} +9 -76
- package/Editor/{TextureResizerWizard.cs → Sprites/TextureResizerWizard.cs} +1 -1
- package/Editor/{TextureSettingsApplier.cs → Sprites/TextureSettingsApplier.cs} +1 -1
- package/Editor/Sprites.meta +3 -0
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +1 -1
- package/Runtime/Core/Helper/DirectoryHelper.cs +64 -0
- package/package.json +2 -1
- package/Editor/SpriteAtlasGenerator.cs +0 -895
- package/Editor/SpriteAtlasGenerator.cs.meta +0 -3
- package/Editor/Utils/GUIHorizontalScope.cs +0 -20
- package/Editor/Utils/GUIHorizontalScope.cs.meta +0 -3
- package/Editor/Utils/GUIIndentScope.cs +0 -20
- package/Editor/Utils/GUIIndentScope.cs.meta +0 -3
- /package/Editor/{AnimationCopier.cs.meta → Sprites/AnimationCopier.cs.meta} +0 -0
- /package/Editor/{AnimationCreator.cs.meta → Sprites/AnimationCreator.cs.meta} +0 -0
- /package/Editor/{SpriteCropper.cs.meta → Sprites/SpriteCropper.cs.meta} +0 -0
- /package/Editor/{SpriteSettingsApplier.cs.meta → Sprites/SpriteSettingsApplier.cs.meta} +0 -0
- /package/Editor/{TextureResizerWizard.cs.meta → Sprites/TextureResizerWizard.cs.meta} +0 -0
- /package/Editor/{TextureSettingsApplier.cs.meta → Sprites/TextureSettingsApplier.cs.meta} +0 -0
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
using UnityEngine;
|
|
10
10
|
using Core.Attributes;
|
|
11
11
|
using Core.Helper;
|
|
12
|
-
using Utils;
|
|
13
12
|
using WallstopStudios.UnityHelpers.Utils;
|
|
14
13
|
|
|
15
14
|
// https://gist.githubusercontent.com/yujen/5e1cd78e2a341260b38029de08a449da/raw/ac60c1002e0e14375de5b2b0a167af00df3f74b4/SeniaAnimationEventEditor.cs
|
|
@@ -173,7 +172,7 @@
|
|
|
173
172
|
|
|
174
173
|
DrawSpritePreview(item);
|
|
175
174
|
|
|
176
|
-
using (new
|
|
175
|
+
using (new EditorGUI.IndentLevelScope())
|
|
177
176
|
{
|
|
178
177
|
RenderAnimationEventItem(item, frame, frameRate);
|
|
179
178
|
if (i != stateCopy.Count - 1)
|
|
@@ -320,7 +319,7 @@
|
|
|
320
319
|
private void RenderAnimationEventItem(AnimationEventItem item, int frame, float frameRate)
|
|
321
320
|
{
|
|
322
321
|
int index = _state.IndexOf(item);
|
|
323
|
-
using (new
|
|
322
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
324
323
|
{
|
|
325
324
|
if (
|
|
326
325
|
1 <= index
|
|
@@ -536,7 +535,7 @@
|
|
|
536
535
|
ParameterInfo[] arrayParameterInfo = item.selectedMethod.GetParameters();
|
|
537
536
|
if (arrayParameterInfo.Length == 1)
|
|
538
537
|
{
|
|
539
|
-
using
|
|
538
|
+
using EditorGUI.IndentLevelScope indent = new();
|
|
540
539
|
|
|
541
540
|
Type paramType = arrayParameterInfo[0].ParameterType;
|
|
542
541
|
if (paramType == typeof(int))
|
|
@@ -679,7 +678,7 @@
|
|
|
679
678
|
}
|
|
680
679
|
else if (!item.isTextureReadable && !string.IsNullOrEmpty(spriteName))
|
|
681
680
|
{
|
|
682
|
-
using (new
|
|
681
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
683
682
|
{
|
|
684
683
|
GUILayout.Label($"Sprite '{spriteName}' required \"Read/Write\" enabled");
|
|
685
684
|
if (item.sprite != null && GUILayout.Button("Fix"))
|
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor.CustomEditors
|
|
2
|
+
{
|
|
3
|
+
#if UNITY_EDITOR
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
using UnityEditor;
|
|
6
|
+
using System.Collections.Generic;
|
|
7
|
+
using System.Linq;
|
|
8
|
+
using Core.Helper;
|
|
9
|
+
using System.IO;
|
|
10
|
+
|
|
11
|
+
public static class PersistentDirectoryGUI
|
|
12
|
+
{
|
|
13
|
+
private static readonly Dictionary<string, bool> ContextFoldoutStates = new();
|
|
14
|
+
|
|
15
|
+
public static float GetDrawFrequentPathsHeight(
|
|
16
|
+
string toolName,
|
|
17
|
+
string contextKey,
|
|
18
|
+
bool allowExpansion = true,
|
|
19
|
+
int topN = 5
|
|
20
|
+
)
|
|
21
|
+
{
|
|
22
|
+
if (PersistentDirectorySettings.Instance == null)
|
|
23
|
+
{
|
|
24
|
+
return 0f;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
float height = 0f;
|
|
28
|
+
DirectoryUsageData[] topPaths = PersistentDirectorySettings.Instance.GetPaths(
|
|
29
|
+
toolName,
|
|
30
|
+
contextKey,
|
|
31
|
+
true,
|
|
32
|
+
topN
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (topPaths.Length <= 0)
|
|
36
|
+
{
|
|
37
|
+
return height;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
height += EditorGUIUtility.singleLineHeight;
|
|
41
|
+
height += topPaths.Length * EditorGUIUtility.singleLineHeight;
|
|
42
|
+
|
|
43
|
+
if (allowExpansion)
|
|
44
|
+
{
|
|
45
|
+
DirectoryUsageData[] allPaths = PersistentDirectorySettings.Instance.GetPaths(
|
|
46
|
+
toolName,
|
|
47
|
+
contextKey,
|
|
48
|
+
false,
|
|
49
|
+
0
|
|
50
|
+
);
|
|
51
|
+
if (allPaths.Length > topN)
|
|
52
|
+
{
|
|
53
|
+
height += EditorGUIUtility.singleLineHeight;
|
|
54
|
+
string foldoutKey = $"{toolName}/{contextKey}_AllPathsHistory";
|
|
55
|
+
bool isExpanded = ContextFoldoutStates.GetValueOrDefault(foldoutKey, false);
|
|
56
|
+
if (isExpanded)
|
|
57
|
+
{
|
|
58
|
+
DirectoryUsageData[] pathsNotAlreadyInTop = allPaths.Skip(topN).ToArray();
|
|
59
|
+
if (pathsNotAlreadyInTop.Any())
|
|
60
|
+
{
|
|
61
|
+
height +=
|
|
62
|
+
pathsNotAlreadyInTop.Length * EditorGUIUtility.singleLineHeight;
|
|
63
|
+
}
|
|
64
|
+
else
|
|
65
|
+
{
|
|
66
|
+
height += EditorGUIUtility.singleLineHeight;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (height > 0)
|
|
73
|
+
{
|
|
74
|
+
height += EditorGUIUtility.standardVerticalSpacing * 2;
|
|
75
|
+
}
|
|
76
|
+
return height;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static float GetPathSelectorHeight(
|
|
80
|
+
string toolName,
|
|
81
|
+
string contextKeyForHistory,
|
|
82
|
+
bool displayFrequentPaths = true
|
|
83
|
+
)
|
|
84
|
+
{
|
|
85
|
+
float height = 0f;
|
|
86
|
+
|
|
87
|
+
height += EditorGUIUtility.singleLineHeight;
|
|
88
|
+
|
|
89
|
+
if (!displayFrequentPaths)
|
|
90
|
+
{
|
|
91
|
+
return height;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
float historyHeight = GetDrawFrequentPathsHeight(toolName, contextKeyForHistory);
|
|
95
|
+
if (historyHeight > 0)
|
|
96
|
+
{
|
|
97
|
+
height += EditorGUIUtility.standardVerticalSpacing;
|
|
98
|
+
height += historyHeight;
|
|
99
|
+
}
|
|
100
|
+
return height;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public static float GetPathSelectorStringHeight(
|
|
104
|
+
SerializedProperty propertyForContext,
|
|
105
|
+
string toolName
|
|
106
|
+
)
|
|
107
|
+
{
|
|
108
|
+
if (propertyForContext is not { propertyType: SerializedPropertyType.String })
|
|
109
|
+
{
|
|
110
|
+
return EditorGUIUtility.singleLineHeight;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
float height = 0f;
|
|
114
|
+
|
|
115
|
+
height += EditorGUIUtility.singleLineHeight;
|
|
116
|
+
|
|
117
|
+
height += EditorGUIUtility.standardVerticalSpacing;
|
|
118
|
+
|
|
119
|
+
string internalContextKey =
|
|
120
|
+
$"{propertyForContext.serializedObject.targetObject.GetType().Name}_{propertyForContext.propertyPath}";
|
|
121
|
+
height += GetPathSelectorHeight(toolName, internalContextKey);
|
|
122
|
+
return height;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public static void PathSelectorString(
|
|
126
|
+
SerializedProperty property,
|
|
127
|
+
string toolName,
|
|
128
|
+
string label,
|
|
129
|
+
GUIContent content
|
|
130
|
+
)
|
|
131
|
+
{
|
|
132
|
+
if (property == null)
|
|
133
|
+
{
|
|
134
|
+
EditorGUILayout.LabelField(
|
|
135
|
+
$"Error: Property is null in {nameof(PathSelectorString)}.",
|
|
136
|
+
EditorStyles.miniBoldLabel
|
|
137
|
+
);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (property.propertyType != SerializedPropertyType.String)
|
|
141
|
+
{
|
|
142
|
+
EditorGUILayout.LabelField(
|
|
143
|
+
$"Error: Property '{property.displayName}' is not a string.",
|
|
144
|
+
EditorStyles.miniBoldLabel
|
|
145
|
+
);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
|
|
150
|
+
PathSelector(
|
|
151
|
+
content,
|
|
152
|
+
property.stringValue,
|
|
153
|
+
toolName,
|
|
154
|
+
property.name,
|
|
155
|
+
chosenPath =>
|
|
156
|
+
{
|
|
157
|
+
property.stringValue = chosenPath;
|
|
158
|
+
property.serializedObject.ApplyModifiedProperties();
|
|
159
|
+
},
|
|
160
|
+
"Select Directory"
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public static void PathSelectorObject(
|
|
165
|
+
SerializedProperty property,
|
|
166
|
+
string toolName,
|
|
167
|
+
string label,
|
|
168
|
+
GUIContent content
|
|
169
|
+
)
|
|
170
|
+
{
|
|
171
|
+
if (property == null)
|
|
172
|
+
{
|
|
173
|
+
EditorGUILayout.LabelField(
|
|
174
|
+
$"Error: Property is null in {nameof(PathSelectorObject)}.",
|
|
175
|
+
EditorStyles.miniBoldLabel
|
|
176
|
+
);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (property.propertyType != SerializedPropertyType.ObjectReference)
|
|
180
|
+
{
|
|
181
|
+
EditorGUILayout.LabelField(
|
|
182
|
+
$"Error: Property '{property.displayName}' is not an Object Reference.",
|
|
183
|
+
EditorStyles.miniBoldLabel
|
|
184
|
+
);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
|
|
188
|
+
PathSelector(
|
|
189
|
+
content,
|
|
190
|
+
property.objectReferenceValue == null
|
|
191
|
+
? string.Empty
|
|
192
|
+
: AssetDatabase.GetAssetPath(property.objectReferenceValue),
|
|
193
|
+
toolName,
|
|
194
|
+
property.name,
|
|
195
|
+
chosenPath =>
|
|
196
|
+
{
|
|
197
|
+
if (!string.IsNullOrWhiteSpace(chosenPath))
|
|
198
|
+
{
|
|
199
|
+
Object defaultFolder = AssetDatabase.LoadAssetAtPath<Object>(chosenPath);
|
|
200
|
+
property.objectReferenceValue = defaultFolder;
|
|
201
|
+
}
|
|
202
|
+
else
|
|
203
|
+
{
|
|
204
|
+
property.objectReferenceValue = null;
|
|
205
|
+
}
|
|
206
|
+
property.serializedObject.ApplyModifiedProperties();
|
|
207
|
+
},
|
|
208
|
+
"Select Directory"
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public static void PathSelectorStringArray(SerializedProperty listProp, string toolName)
|
|
213
|
+
{
|
|
214
|
+
if (listProp == null)
|
|
215
|
+
{
|
|
216
|
+
EditorGUILayout.LabelField(
|
|
217
|
+
$"Error: Property is null in {nameof(PathSelectorStringArray)}.",
|
|
218
|
+
EditorStyles.miniBoldLabel
|
|
219
|
+
);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
224
|
+
{
|
|
225
|
+
EditorGUILayout.LabelField("Number of Directories:", GUILayout.Width(150));
|
|
226
|
+
int currentSize = listProp.arraySize;
|
|
227
|
+
int newSize = EditorGUILayout.IntField(currentSize, GUILayout.Width(50));
|
|
228
|
+
if (newSize != currentSize)
|
|
229
|
+
{
|
|
230
|
+
newSize = Mathf.Max(0, newSize);
|
|
231
|
+
listProp.arraySize = newSize;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
using (new EditorGUI.IndentLevelScope())
|
|
236
|
+
{
|
|
237
|
+
for (int i = 0; i < listProp.arraySize; i++)
|
|
238
|
+
{
|
|
239
|
+
SerializedProperty elementProp = listProp.GetArrayElementAtIndex(i);
|
|
240
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
241
|
+
{
|
|
242
|
+
int currentIndex = i;
|
|
243
|
+
PathSelector(
|
|
244
|
+
new GUIContent($"Path {i + 1}"),
|
|
245
|
+
elementProp.stringValue,
|
|
246
|
+
toolName,
|
|
247
|
+
listProp.name,
|
|
248
|
+
chosenPath =>
|
|
249
|
+
{
|
|
250
|
+
SerializedProperty currentElementProp =
|
|
251
|
+
listProp.GetArrayElementAtIndex(currentIndex);
|
|
252
|
+
currentElementProp.stringValue = chosenPath;
|
|
253
|
+
currentElementProp.serializedObject.ApplyModifiedProperties();
|
|
254
|
+
},
|
|
255
|
+
$"Select Directory {i + 1}"
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
if (GUILayout.Button("-", GUILayout.Width(25)))
|
|
259
|
+
{
|
|
260
|
+
elementProp.stringValue = string.Empty;
|
|
261
|
+
listProp.DeleteArrayElementAtIndex(i);
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
EditorGUILayout.Space(3);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (GUILayout.Button("Add New Directory Path", GUILayout.Width(200)))
|
|
270
|
+
{
|
|
271
|
+
listProp.InsertArrayElementAtIndex(listProp.arraySize);
|
|
272
|
+
listProp.GetArrayElementAtIndex(listProp.arraySize - 1).stringValue = string.Empty;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public static void PathSelectorObjectArray(SerializedProperty listProp, string toolName)
|
|
277
|
+
{
|
|
278
|
+
if (listProp == null)
|
|
279
|
+
{
|
|
280
|
+
EditorGUILayout.LabelField(
|
|
281
|
+
$"Error: Property is null in {nameof(PathSelectorObjectArray)}.",
|
|
282
|
+
EditorStyles.miniBoldLabel
|
|
283
|
+
);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
288
|
+
{
|
|
289
|
+
EditorGUILayout.LabelField("Number of Directories:", GUILayout.Width(150));
|
|
290
|
+
int currentSize = listProp.arraySize;
|
|
291
|
+
int newSize = EditorGUILayout.IntField(currentSize, GUILayout.Width(50));
|
|
292
|
+
if (newSize != currentSize)
|
|
293
|
+
{
|
|
294
|
+
newSize = Mathf.Max(0, newSize);
|
|
295
|
+
listProp.arraySize = newSize;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
using (new EditorGUI.IndentLevelScope())
|
|
300
|
+
{
|
|
301
|
+
for (int i = 0; i < listProp.arraySize; i++)
|
|
302
|
+
{
|
|
303
|
+
SerializedProperty elementProp = listProp.GetArrayElementAtIndex(i);
|
|
304
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
305
|
+
{
|
|
306
|
+
int currentIndex = i;
|
|
307
|
+
PathSelector(
|
|
308
|
+
new GUIContent($"Path {i + 1}"),
|
|
309
|
+
elementProp.objectReferenceValue == null
|
|
310
|
+
? string.Empty
|
|
311
|
+
: AssetDatabase.GetAssetPath(elementProp.objectReferenceValue),
|
|
312
|
+
toolName,
|
|
313
|
+
listProp.name,
|
|
314
|
+
chosenPath =>
|
|
315
|
+
{
|
|
316
|
+
SerializedProperty currentElementProp =
|
|
317
|
+
listProp.GetArrayElementAtIndex(currentIndex);
|
|
318
|
+
if (!string.IsNullOrWhiteSpace(chosenPath))
|
|
319
|
+
{
|
|
320
|
+
Object defaultFolder = AssetDatabase.LoadAssetAtPath<Object>(
|
|
321
|
+
chosenPath
|
|
322
|
+
);
|
|
323
|
+
currentElementProp.objectReferenceValue = defaultFolder;
|
|
324
|
+
}
|
|
325
|
+
else
|
|
326
|
+
{
|
|
327
|
+
currentElementProp.objectReferenceValue = null;
|
|
328
|
+
}
|
|
329
|
+
currentElementProp.serializedObject.ApplyModifiedProperties();
|
|
330
|
+
},
|
|
331
|
+
$"Select Directory {i + 1}"
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
if (GUILayout.Button("-", GUILayout.Width(25)))
|
|
335
|
+
{
|
|
336
|
+
elementProp.stringValue = "";
|
|
337
|
+
listProp.DeleteArrayElementAtIndex(i);
|
|
338
|
+
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
EditorGUILayout.Space(3);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (GUILayout.Button("Add New Directory Path", GUILayout.Width(200)))
|
|
348
|
+
{
|
|
349
|
+
listProp.InsertArrayElementAtIndex(listProp.arraySize);
|
|
350
|
+
listProp.GetArrayElementAtIndex(listProp.arraySize - 1).objectReferenceValue = null;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public static string PathSelector(
|
|
355
|
+
GUIContent label,
|
|
356
|
+
string currentPath,
|
|
357
|
+
string toolName,
|
|
358
|
+
string contextKey,
|
|
359
|
+
System.Action<string> onPathChosen,
|
|
360
|
+
string dialogTitle = "Select Folder",
|
|
361
|
+
float textFieldWidthOverride = -1f
|
|
362
|
+
)
|
|
363
|
+
{
|
|
364
|
+
if (onPathChosen == null)
|
|
365
|
+
{
|
|
366
|
+
Debug.LogError(
|
|
367
|
+
"PersistentDirectoryGUI.PathSelector: onPathChosen callback cannot be null."
|
|
368
|
+
);
|
|
369
|
+
return currentPath;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
string pathInTextField = currentPath;
|
|
373
|
+
|
|
374
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
375
|
+
{
|
|
376
|
+
if (textFieldWidthOverride > 0)
|
|
377
|
+
{
|
|
378
|
+
pathInTextField = EditorGUILayout.TextField(
|
|
379
|
+
label,
|
|
380
|
+
pathInTextField,
|
|
381
|
+
GUILayout.Width(textFieldWidthOverride)
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
else
|
|
385
|
+
{
|
|
386
|
+
pathInTextField = EditorGUILayout.TextField(label, pathInTextField);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (GUILayout.Button("Browse...", GUILayout.ExpandWidth(false)))
|
|
390
|
+
{
|
|
391
|
+
string initialBrowsePath = Application.dataPath;
|
|
392
|
+
if (!string.IsNullOrWhiteSpace(pathInTextField))
|
|
393
|
+
{
|
|
394
|
+
try
|
|
395
|
+
{
|
|
396
|
+
string fullPotentialPath = Path.GetFullPath(
|
|
397
|
+
pathInTextField.StartsWith("Assets")
|
|
398
|
+
? pathInTextField
|
|
399
|
+
: Path.Combine(Application.dataPath, "..", pathInTextField)
|
|
400
|
+
);
|
|
401
|
+
if (Directory.Exists(fullPotentialPath))
|
|
402
|
+
{
|
|
403
|
+
initialBrowsePath = fullPotentialPath;
|
|
404
|
+
}
|
|
405
|
+
else
|
|
406
|
+
{
|
|
407
|
+
string dirName = Path.GetDirectoryName(fullPotentialPath);
|
|
408
|
+
if (Directory.Exists(dirName))
|
|
409
|
+
{
|
|
410
|
+
initialBrowsePath = dirName;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
catch
|
|
415
|
+
{
|
|
416
|
+
// Swallow
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (!Directory.Exists(initialBrowsePath))
|
|
420
|
+
{
|
|
421
|
+
initialBrowsePath = Application.dataPath;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
string selectedPathSys = EditorUtility.OpenFolderPanel(
|
|
425
|
+
dialogTitle,
|
|
426
|
+
initialBrowsePath,
|
|
427
|
+
""
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
if (!string.IsNullOrWhiteSpace(selectedPathSys))
|
|
431
|
+
{
|
|
432
|
+
string processedPath = selectedPathSys.SanitizePath();
|
|
433
|
+
if (processedPath.StartsWith(Application.dataPath.SanitizePath()))
|
|
434
|
+
{
|
|
435
|
+
processedPath =
|
|
436
|
+
"Assets"
|
|
437
|
+
+ processedPath.Substring(
|
|
438
|
+
Application.dataPath.SanitizePath().Length
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
pathInTextField = processedPath;
|
|
443
|
+
PersistentDirectorySettings.Instance.RecordPath(
|
|
444
|
+
toolName,
|
|
445
|
+
contextKey,
|
|
446
|
+
processedPath
|
|
447
|
+
);
|
|
448
|
+
onPathChosen.Invoke(processedPath);
|
|
449
|
+
GUI.FocusControl(null);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
DrawFrequentPaths(
|
|
455
|
+
toolName,
|
|
456
|
+
contextKey,
|
|
457
|
+
chosenHistoryPath =>
|
|
458
|
+
{
|
|
459
|
+
pathInTextField = chosenHistoryPath;
|
|
460
|
+
PersistentDirectorySettings.Instance.RecordPath(
|
|
461
|
+
toolName,
|
|
462
|
+
contextKey,
|
|
463
|
+
chosenHistoryPath
|
|
464
|
+
);
|
|
465
|
+
onPathChosen.Invoke(chosenHistoryPath);
|
|
466
|
+
GUI.FocusControl(null);
|
|
467
|
+
},
|
|
468
|
+
true,
|
|
469
|
+
5,
|
|
470
|
+
"History:"
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
return pathInTextField;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
public static void DrawFrequentPaths(
|
|
477
|
+
string toolName,
|
|
478
|
+
string contextKey,
|
|
479
|
+
System.Action<string> onPathClickedFromHistory,
|
|
480
|
+
bool allowExpansion = true,
|
|
481
|
+
int topN = 5,
|
|
482
|
+
string listLabel = "Frequent Paths:"
|
|
483
|
+
)
|
|
484
|
+
{
|
|
485
|
+
if (PersistentDirectorySettings.Instance == null)
|
|
486
|
+
{
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (onPathClickedFromHistory == null)
|
|
491
|
+
{
|
|
492
|
+
Debug.LogError(
|
|
493
|
+
"PersistentDirectoryGUI.DrawFrequentPaths: onPathClickedFromHistory callback cannot be null."
|
|
494
|
+
);
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
DirectoryUsageData[] topPaths = PersistentDirectorySettings.Instance.GetPaths(
|
|
499
|
+
toolName,
|
|
500
|
+
contextKey,
|
|
501
|
+
true,
|
|
502
|
+
topN
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
if (topPaths.Length <= 0)
|
|
506
|
+
{
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
using (new EditorGUILayout.HorizontalScope())
|
|
511
|
+
{
|
|
512
|
+
GUILayout.Space(EditorGUI.indentLevel * 15f + 15f);
|
|
513
|
+
using (new EditorGUILayout.VerticalScope())
|
|
514
|
+
{
|
|
515
|
+
EditorGUILayout.LabelField(listLabel, EditorStyles.miniBoldLabel);
|
|
516
|
+
foreach (DirectoryUsageData dirData in topPaths)
|
|
517
|
+
{
|
|
518
|
+
if (
|
|
519
|
+
GUILayout.Button(
|
|
520
|
+
new GUIContent($"({dirData.count}) {dirData.path}", dirData.path),
|
|
521
|
+
EditorStyles.miniButtonLeft
|
|
522
|
+
)
|
|
523
|
+
)
|
|
524
|
+
{
|
|
525
|
+
onPathClickedFromHistory.Invoke(dirData.path);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (!allowExpansion)
|
|
530
|
+
{
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
string foldoutKey = $"{toolName}/{contextKey}_AllPathsHistory";
|
|
535
|
+
ContextFoldoutStates.TryAdd(foldoutKey, false);
|
|
536
|
+
|
|
537
|
+
DirectoryUsageData[] allPaths = PersistentDirectorySettings.Instance.GetPaths(
|
|
538
|
+
toolName,
|
|
539
|
+
contextKey,
|
|
540
|
+
false,
|
|
541
|
+
0
|
|
542
|
+
);
|
|
543
|
+
if (allPaths.Length <= topN)
|
|
544
|
+
{
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
ContextFoldoutStates[foldoutKey] = EditorGUILayout.Foldout(
|
|
549
|
+
ContextFoldoutStates[foldoutKey],
|
|
550
|
+
"Show All History (" + allPaths.Length + ")",
|
|
551
|
+
true,
|
|
552
|
+
EditorStyles.foldout
|
|
553
|
+
);
|
|
554
|
+
if (!ContextFoldoutStates[foldoutKey])
|
|
555
|
+
{
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
DirectoryUsageData[] pathsNotAlreadyInTop = allPaths.Skip(topN).ToArray();
|
|
560
|
+
if (0 < pathsNotAlreadyInTop.Length)
|
|
561
|
+
{
|
|
562
|
+
foreach (DirectoryUsageData dirData in pathsNotAlreadyInTop)
|
|
563
|
+
{
|
|
564
|
+
if (
|
|
565
|
+
GUILayout.Button(
|
|
566
|
+
new GUIContent(
|
|
567
|
+
$"({dirData.count}) {dirData.path}",
|
|
568
|
+
dirData.path
|
|
569
|
+
),
|
|
570
|
+
EditorStyles.miniButtonLeft
|
|
571
|
+
)
|
|
572
|
+
)
|
|
573
|
+
{
|
|
574
|
+
onPathClickedFromHistory.Invoke(dirData.path);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
else
|
|
579
|
+
{
|
|
580
|
+
EditorGUILayout.LabelField(
|
|
581
|
+
"All paths already displayed above.",
|
|
582
|
+
EditorStyles.centeredGreyMiniLabel
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
#endif
|
|
590
|
+
}
|