using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
// using Action = Unity.Plastic.Antlr3.Runtime.Misc.Action;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
#endif
namespace XericUI.Helper
{
public static class EditorOverrideUIHelper
{
///
/// 替换菜单组件上下文
///
///
/// 在组件上使用如下的方法定义替换
///
/// [MenuItem("CONTEXT/XXX/ReplaceToXXX", true)]
/// private static bool ValidateReplaceWithCustomScrollRect(MenuCommand command)
/// => command.context is ScrollRect;
///
/// [MenuItem("CONTEXT/XXX/ReplaceToXXX", false, 10)]
/// private static void ReplaceWithCustomScrollRect(MenuCommand command)
/// => command.ReplaceCommandContext<SourceXXX, TargetXXX>();
///
/// 不过实测unity的json序列化也无法处理引用,还是需要手动将引用类型传过来
///
///
#if UNITY_EDITOR
public static TTarget ReplaceCommandContext(this MenuCommand command)
where TSource : Component
where TTarget : Component
{
TSource original = command.context as TSource;
if (original == null) return null;
GameObject go = original.gameObject;
// 标记撤销
Undo.SetCurrentGroupName($"替换{typeof(TSource).Name}为{typeof(TTarget).Name}");
int undoGroup = Undo.GetCurrentGroup();
Undo.RecordObject(go, "替换组件");
// 主要的替换流程,不过unity好像也只能处理非引用对象,废物Unity
string jsonData = EditorJsonUtility.ToJson(original);
Object.DestroyImmediate(original);
TTarget newComponent = go.AddComponent();
EditorJsonUtility.FromJsonOverwrite(jsonData, newComponent);
EditorUtility.SetDirty(go);
// 结束撤销标记
Undo.RegisterCreatedObjectUndo(newComponent, "替换组件");
Undo.CollapseUndoOperations(undoGroup);
Debug.Log("组件替换完成");
return newComponent;
}
#else
private static void ReplaceCommandContext(this Object command)
=> throw new Exception("不能在运行时使用XericUIActionVessel编辑器功能");
#endif
#if UNITY_EDITOR
public static void ReplaceCommandContext(
this MenuCommand command, Func referenceExtractor, Action referenceApplier)
where TSource : Component
where TTarget : Component
{
TSource original = command.context as TSource;
var references = referenceExtractor(original);
TTarget component = command.ReplaceCommandContext();
referenceApplier(component, references);
}
#else
private static void ReplaceCommandContext(this Object command,
Func referenceExtractor, Action referenceApplier)
=> throw new Exception("不能在运行时使用XericUIActionVessel编辑器功能");
#endif
}
}