using System; using System.Collections.Generic; using System.IO; using Unity.UI.Builder; using UnityEditor.Experimental; using UnityEditor.VFX.UI; using UnityEngine; using UnityEngine.UIElements; using UnityEngine.VFX; namespace UnityEditor.VFX { internal interface IVFXTemplateDescriptor { string header { get; } } internal class VFXTemplateWindow : EditorWindow { internal interface ISaveFileDialogHelper { string OpenSaveFileDialog(string title, string defaultName, string extension, string message); } private class SaveFileDialogHelper : ISaveFileDialogHelper { public string OpenSaveFileDialog(string title, string defaultName, string extension, string message) => EditorUtility.SaveFilePanelInProject(title, defaultName, extension, message); } private class VFXTemplateSection : IVFXTemplateDescriptor { public VFXTemplateSection(string text) { header = text; } public string header { get; } } private const string VFXTemplateWindowDocUrl = "https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@{0}/manual/Templates-window.html"; private const string BuiltInCategory = "Default VFX Graph Templates"; private const string EmptyTemplateName = "Empty VFX"; private const string EmptyTemplateDescription = "Create a completely empty VFX asset"; private const string LastSelectedGuidKey = "VFXTemplateWindow.LastSelectedGuid"; private const string CreateNewVFXAssetTitle = "Create new VFX Asset"; private const string InsertTemplateTitle = "Insert a template into current VFX Asset"; private static readonly Dictionary s_ModeToTitle = new () { { CreateMode.CreateNew, CreateNewVFXAssetTitle }, { CreateMode.Insert, InsertTemplateTitle }, { CreateMode.None, CreateNewVFXAssetTitle }, }; private readonly List> m_TemplatesTree = new (); private readonly ISaveFileDialogHelper m_SaveFileDialogHelper = new SaveFileDialogHelper(); private TreeView m_ListOfTemplates; private Texture2D m_CustomTemplateIcon; private Image m_DetailsScreenshot; private Label m_DetailsTitle; private Label m_DetailsDescription; private VisualTreeAsset m_ItemTemplate; private Action m_VFXAssetCreationCallback; private string m_LastSelectedTemplatePath; private int m_LastSelectedIndex; private CreateMode m_CurrentMode; private Action m_UserCallback; private string m_LastSelectedTemplateGuid; private VFXView m_VfxView; private VFXTemplateDescriptor m_SelectedTemplate; private enum CreateMode { CreateNew, Insert, None, } public static void ShowCreateFromTemplate(VFXView vfxView, Action callback) => ShowInternal(vfxView, CreateMode.CreateNew, callback); public static void ShowInsertTemplate(VFXView vfxView) => ShowInternal(vfxView, CreateMode.Insert); public static void PickTemplate(Action callback) => ShowInternal(null, CreateMode.None, callback); private static void ShowInternal(VFXView vfxView, CreateMode mode, Action callback = null) { var templateWindow = EditorWindow.GetWindow(true, s_ModeToTitle[mode], false); templateWindow.Setup(vfxView, mode, callback); } private void Setup(VFXView vfxView, CreateMode mode, Action callback) { minSize = new Vector2(800, 300); m_VfxView = vfxView; m_UserCallback = callback; m_CurrentMode = mode; SetCallBack(); LoadTemplates(); } private void CreateGUI() { m_ItemTemplate = VFXView.LoadUXML("VFXTemplateItem"); var tpl = VFXView.LoadUXML("VFXTemplateWindow"); tpl.CloneTree(rootVisualElement); rootVisualElement.AddStyleSheetPath("VFXTemplateWindow"); rootVisualElement.name = "VFXTemplateWindowRoot"; rootVisualElement.Q