1+ /**
2+ * CustomScriptTemplateEditor.cs
3+ * Created by: João Borks [[email protected] ] 4+ * Created on: 7/13/2019 (en-US)
5+ */
6+
7+ using System . IO ;
8+ using System . Linq ;
9+ using UnityEditor ;
10+ using UnityEditor . SceneManagement ;
11+ using UnityEditor . UIElements ;
12+ using UnityEngine ;
13+ using UnityEngine . UIElements ;
14+
15+ namespace MyUnityTools . ScriptTemplates
16+ {
17+ public class ScriptTemplatesEditor : EditorWindow
18+ {
19+ /// <summary>
20+ /// The name of the <see cref="authorName"/> string field saved on <see cref="EditorPrefs"/>
21+ /// </summary>
22+ public const string AuthorNameField = "com.myunitytools.cst.authorName" ;
23+ /// <summary>
24+ /// The name of the <see cref="authorEmail"/> string field saved on <see cref="EditorPrefs"/>
25+ /// </summary>
26+ public const string AuthorEmailField = "com.myunitytools.cst.authorEmail" ;
27+ /// <summary>
28+ /// The name of the <see cref="localGUID"/> string field saved on <see cref="EditorPrefs"/>
29+ /// </summary>
30+ public const string LocalGUIDField = "com.myunitytools.cst.localguid" ;
31+ /// <summary>
32+ /// Package path for accessing script templates and visual elements
33+ /// </summary>
34+ public const string PackageRootPath = "Packages/com.myunitytools.scripttemplate/" ;
35+ /// <summary>
36+ /// Project path for storing script templates
37+ /// </summary>
38+ public const string LocalTemplatesPath = "Assets/ScriptTemplates/" ;
39+ /// <summary>
40+ /// Editor path for storing script templates
41+ /// </summary>
42+ public static readonly string EditorTemplatesPath = EditorApplication . applicationPath . Replace ( "Unity.exe" , "" ) + "/Data/Resources/ScriptTemplates/" ;
43+
44+ const string EditorRestartMesssage = "Copying Script Templates will requre Editor restart in order to apply the changes. Do you want to restart now?" ;
45+
46+ [ MenuItem ( "Assets/Script Templates Editor" , false , 800 ) ]
47+ public static void ShowWindow ( ) => GetWindow < ScriptTemplatesEditor > ( "Script Templates" ) . minSize = new Vector2 ( 300 , 250 ) ;
48+
49+ void OnEnable ( )
50+ {
51+ var visualTree = AssetDatabase . LoadAssetAtPath < VisualTreeAsset > ( PackageRootPath + "UIToolkit/ScriptTemplateWindow.uxml" ) ;
52+ rootVisualElement . Add ( visualTree . CloneTree ( ) ) ;
53+ var styles = AssetDatabase . LoadAssetAtPath < StyleSheet > ( PackageRootPath + "UIToolkit/Styles/ScriptTemplateStyles.uss" ) ;
54+ rootVisualElement . styleSheets . Add ( styles ) ;
55+
56+ DrawInfoView ( ) ;
57+ DrawTemplateView ( ) ;
58+ }
59+
60+ void DrawInfoView ( )
61+ {
62+ var saveButton = rootVisualElement . Q < Button > ( "save-button" ) ;
63+
64+ var authorField = rootVisualElement . Q < TextField > ( "author" ) ;
65+ authorField . SetValueWithoutNotify ( EditorPrefs . GetString ( AuthorNameField , string . Empty ) ) ;
66+ authorField . RegisterValueChangedCallback ( e => saveButton . SetEnabled ( ! isAuthorUpdated ( e . newValue ) && ! string . IsNullOrEmpty ( authorField . value ) ) ) ;
67+
68+ var emailField = rootVisualElement . Q < TextField > ( "email" ) ;
69+ emailField . SetValueWithoutNotify ( EditorPrefs . GetString ( AuthorEmailField , string . Empty ) ) ;
70+ emailField . RegisterValueChangedCallback ( e => saveButton . SetEnabled ( ! isEmailUpdated ( e . newValue ) && ! string . IsNullOrEmpty ( authorField . value ) ) ) ;
71+
72+ var clearButton = rootVisualElement . Q < Button > ( "clear-button" ) ;
73+ clearButton . SetEnabled ( EditorPrefs . HasKey ( AuthorNameField ) || EditorPrefs . HasKey ( AuthorEmailField ) ) ;
74+ clearButton . clicked += ( ) =>
75+ {
76+ EditorPrefs . DeleteKey ( AuthorNameField ) ;
77+ EditorPrefs . DeleteKey ( AuthorEmailField ) ;
78+ saveButton . SetEnabled ( ! string . IsNullOrEmpty ( authorField . value ) ) ;
79+ clearButton . SetEnabled ( false ) ;
80+ } ;
81+
82+ saveButton . SetEnabled ( false ) ;
83+ saveButton . clicked += ( ) =>
84+ {
85+ EditorPrefs . SetString ( AuthorNameField , authorField . value ) ;
86+ EditorPrefs . SetString ( AuthorEmailField , emailField . value ) ;
87+ saveButton . SetEnabled ( false ) ;
88+ clearButton . SetEnabled ( true ) ;
89+ } ;
90+
91+ bool isAuthorUpdated ( string author ) => author == EditorPrefs . GetString ( AuthorNameField , string . Empty ) ;
92+
93+ bool isEmailUpdated ( string email ) => email == EditorPrefs . GetString ( AuthorEmailField , string . Empty ) ;
94+ }
95+
96+ void DrawTemplateView ( )
97+ {
98+ var templates = GetPackageScriptTemplates ( ) ;
99+ var listView = rootVisualElement . Q < ListView > ( "template-list" ) ;
100+ listView . makeItem = ( ) =>
101+ {
102+ var objectField = new ObjectField ( string . Empty )
103+ {
104+ allowSceneObjects = false ,
105+ objectType = typeof ( TextAsset )
106+ } ;
107+ objectField . SetEnabled ( false ) ;
108+ return objectField ;
109+ } ;
110+ listView . bindItem = ( element , i ) => ( element as ObjectField ) . SetValueWithoutNotify ( templates [ i ] ) ;
111+ listView . itemsSource = templates ;
112+ listView . itemHeight = 20 ;
113+ listView . selectionType = SelectionType . Single ;
114+ listView . onSelectionChanged += selection => Selection . activeObject = ( Object ) selection . FirstOrDefault ( ) ;
115+
116+ var projectButton = rootVisualElement . Q < Button > ( "copy-project-button" ) ;
117+ projectButton . clicked += ( ) =>
118+ {
119+ var shouldRestart = EditorUtility . DisplayDialog ( "Editor Restart" , EditorRestartMesssage , "Yes" , "No" ) ;
120+ var length = templates . Length ;
121+ if ( ! AssetDatabase . IsValidFolder ( LocalTemplatesPath ) )
122+ AssetDatabase . CreateFolder ( "Assets" , "ScriptTemplates" ) ;
123+ for ( int i = 0 ; i < length ; i ++ )
124+ AssetDatabase . CopyAsset ( AssetDatabase . GetAssetPath ( templates [ i ] ) , LocalTemplatesPath + templates [ i ] . name + ".txt" ) ;
125+ if ( shouldRestart && EditorSceneManager . SaveCurrentModifiedScenesIfUserWantsTo ( ) )
126+ EditorApplication . OpenProject ( Path . Combine ( Application . dataPath , ".." ) ) ;
127+ } ;
128+
129+ var editorButton = rootVisualElement . Q < Button > ( "copy-editor-button" ) ;
130+ editorButton . clicked += ( ) =>
131+ {
132+ var shouldRestart = EditorUtility . DisplayDialog ( "Editor Restart" , EditorRestartMesssage , "Yes" , "No" ) ;
133+ var length = templates . Length ;
134+ for ( int i = 0 ; i < length ; i ++ )
135+ File . Copy ( AssetDatabase . GetAssetPath ( templates [ i ] ) , EditorTemplatesPath + templates [ i ] . name + ".txt" ) ;
136+ if ( shouldRestart && EditorSceneManager . SaveCurrentModifiedScenesIfUserWantsTo ( ) )
137+ EditorApplication . OpenProject ( Path . Combine ( Application . dataPath , ".." ) ) ;
138+ } ;
139+ }
140+
141+ /// <summary>
142+ /// Gets all Script Templates included in this package
143+ /// </summary>
144+ TextAsset [ ] GetPackageScriptTemplates ( )
145+ {
146+ var files = Directory . GetFiles ( PackageRootPath + "ScriptTemplates/" , "*.txt" ) ;
147+ var assets = new TextAsset [ files . Length ] ;
148+ var length = files . Length ;
149+ for ( int i = 0 ; i < length ; i ++ )
150+ assets [ i ] = AssetDatabase . LoadAssetAtPath < TextAsset > ( files [ i ] ) ;
151+ return assets ;
152+ }
153+ }
154+ }
0 commit comments