iFactory.Cutting.Unity/Assets/BITKit/UnityEditor/ScriptableObjectGroupEditor.cs

199 lines
5.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BITKit.UX;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace BITKit.GameEditor
{
public class ScriptableObjectGroupEditor<T> : EditorWindow where T : ScriptableObject
{
protected virtual string AssetsPath => $"Assets/Artists/";
protected readonly List<T> List=new();
private ListView _listView;
protected VisualElement _container { get; private set; }
private Button _createButton;
private void OnEnable()
{
RebuildList();
rootVisualElement.style.flexDirection = FlexDirection.Row;
var css = AssetDatabase.LoadAssetAtPath<StyleSheet>(BITEditorUtils.InspectorPath);
rootVisualElement.styleSheets.Add(css);
var leftSlider = rootVisualElement.Create<VisualElement>();
leftSlider.name = "LeftSlider";
var toolbarContainer = leftSlider.Create<VisualElement>();
toolbarContainer.style.alignSelf = Align.Auto;
toolbarContainer.style.flexDirection = FlexDirection.Row;
var refreshButton = toolbarContainer.Create<Button>();
refreshButton.text = "刷新";
refreshButton.clicked += () =>
{
RebuildList();
_listView.Rebuild();
};
var container = leftSlider.Create<VisualElement>();
var listViewContainer = container.Create<VisualElement>();
var createContainer = listViewContainer.Create<VisualElement>();
createContainer.style.flexDirection = FlexDirection.Row;
var nameField = createContainer.Create<TextField>();
nameField.style.flexGrow = 1;
_createButton=createContainer.Create<Button>();
_createButton.text = "创建";
_createButton.clicked += () => CreateScriptableObject(nameField.value);
container.style.flexDirection = FlexDirection.Row;
listViewContainer.style.flexDirection = FlexDirection.Column;
listViewContainer.style.flexGrow = 1;
listViewContainer.Create<Label>().text = $"获取到:{List.Count}个配置";
listViewContainer.AddToClassList("pa-8");
_listView = leftSlider.Create<ListView>();
_listView.makeItem = MakeItem;
_listView.bindItem = BindItem;
_listView.itemsChosen += ItemsChosen;
_listView.style.minWidth = 128;
_listView.style.flexGrow = 1;
_listView.itemsSource = List;
var scroll = rootVisualElement.Create<ScrollView>();
scroll.name = "Scroll";
scroll.style.flexGrow = 1;
_container = scroll.Create<GroupBox>();
var pingButton = toolbarContainer.Create<Button>();
pingButton.text = "Ping";
pingButton.clicked += () =>
{
if (_listView.selectedIndex < 0) return;
var item = List[_listView.selectedIndex];
EditorGUIUtility.PingObject(item);
};
//_container.style.flexGrow = 1;
Debug.Log(
$"{GetType().Name} 已初始化,从{AssetsPath}获取到{List.Count}个{typeof(T).Name}");
}
protected virtual void ItemsChosen(IEnumerable<object> obj)
{
var selected = obj.FirstOrDefault() as Object;
var serializedObject = new SerializedObject(selected);
BITInspectorExtensions.FillDefaultInspector(_container,serializedObject, true);
_container.Bind(serializedObject);
}
protected virtual VisualElement MakeItem()
{
var container = new VisualElement();
var icon = container.Create<VisualElement>(UXConstant.Icon);
var label = container.Create<Label>(UXConstant.ContextLabel);
container.style.flexDirection = FlexDirection.Row;
container.style.alignContent = Align.Center;
container.style.alignItems = Align.Center;
icon.style.width = 24;
icon.style.height = 24;
container.AddManipulator(new ContextualMenuManipulator((evt) =>
{
evt.menu.AppendAction("复制", Copy, DropdownMenuAction.AlwaysEnabled);
//evt.menu.AppendAction("Second menu item", (x) => Debug.Log("Second!!!!"), DropdownMenuAction.AlwaysEnabled);
}));
return container;
void Copy(DropdownMenuAction dropdownMenuAction)
{
if (container.userData is not ScriptableObject scriptableObject) return;
var path = AssetDatabase.GetAssetPath(scriptableObject);
var folder = Path.GetDirectoryName(path)!;
path = Path.Combine(folder, $"{scriptableObject.name}Copy.asset");
var newObject = CreateInstance<T>();
AssetDatabase.CreateAsset(newObject, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log($"复制成功:{path}");
}
}
protected virtual void BindItem(VisualElement arg1, int arg2)
{
try
{
var item = List[arg2];
arg1.Q<Label>().text = item.name;
arg1.userData = item;
}
catch (Exception e)
{
Debug.LogException(e);
}
}
protected void RebuildList()
{
List.Clear();
var paths = AssetDatabase.FindAssets($"t:{typeof(T).Name}");
var allItem =
(
from path in paths.Select(AssetDatabase.GUIDToAssetPath)
select AssetDatabase.LoadAssetAtPath<ScriptableObject>(path)
).ToArray();
List.AddRange(allItem.Cast<T>());
}
protected virtual void CreateScriptableObject(string name)
{
if (string.IsNullOrEmpty(name))
{
name = $"New {typeof(T).Name}";
}
var path = $"{AssetsPath}{name}.asset";
if (EditorUtility.DisplayDialog("创建", $"是否创建{name}与{path}?", "是", "否") is false) return;
new DirectoryInfo(Path.GetDirectoryName(path)!).Create();
var item = CreateInstance<T>();
item.name = name;
AssetDatabase.CreateAsset(item, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
List.Add(item);
_listView.Rebuild();
ItemsChosen(new[] {item});
}
}
}