HKI Core
PlaylistEditor.cs
Go to the documentation of this file.
1 #pragma warning disable 0168
2 using UnityEngine;
3 using UnityEditor;
5 using System;
6 using System.Collections.Generic;
7 
8 namespace HKI.Core.Audio.Editor
9 {
13  [CustomEditor(typeof(Playlist))]
14  public class PlaylistEditor : UnityEditor.Editor
15  {
16  // Private variables
17  const string playlistPlayTypeSPName = "PlaylistPlayType";
18  const string clipsSPName = "Clips";
19 
20  const string clipSPName = "Clip";
21  const string volumeSPName = "Volume";
22  const string pitchSPName = "Pitch";
23 
24  SerializedProperty playlistPlayTypeSP = null;
25  SerializedProperty clipsSP = null;
26 
27  ReorderableList clipsRL = null;
28  List<float> clipsRLHeights = new List<float>();
29  Texture2D highlightTextureRL = null;
30 
31  bool update = false;
32  bool delete = false;
33  int deleteIndex = 0;
34  UnityEngine.Object updateDeleteObject = null;
35 
36  // OnEnable function
37  void OnEnable()
38  {
39  playlistPlayTypeSP = serializedObject.FindProperty(playlistPlayTypeSPName);
40  clipsSP = serializedObject.FindProperty(clipsSPName);
41 
42  clipsRL = new ReorderableList(serializedObject, clipsSP, true, true, false, false);
43  clipsRL.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Sound Clips"); };
44  clipsRL.drawElementCallback = OnDrawElement_ClipsRL;
45  clipsRL.elementHeightCallback = OnElementHeight_ClipsRL;
46  clipsRL.drawElementBackgroundCallback = OnDrawElementBackground_ClipsRL;
47 
48  float heightSize = EditorGUIUtility.singleLineHeight * 1.25f;
49  for (int i = 0; i < clipsSP.arraySize; i++)
50  clipsRLHeights.Add(heightSize);
51 
52  OnHeightsChanged_ClipsRL();
53 
54  highlightTextureRL = new Texture2D(1, 1);
55  highlightTextureRL.SetPixel(0, 0, new Color(0.2f, 0.2f, 0.2f, 1.0f));
56  highlightTextureRL.Apply();
57  }
58 
59  // OnInspectorGUI function
60  public override void OnInspectorGUI()
61  {
62  serializedObject.Update();
63 
64  GeneralSettings();
65 
66  EditorGUILayout.Space();
67 
68  DrawList();
69 
70  AddNewSoundClip();
71 
72  serializedObject.ApplyModifiedProperties();
73  }
74 
75  // Helper functions
77  {
78  EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
79 
80  EditorGUILayout.PropertyField(playlistPlayTypeSP);
81  }
82 
84  {
85  if (GUILayout.Button("Add New Sound Clip", GUILayout.Height(30.0f)))
86  {
87  SoundClip soundClip = ScriptableObject.CreateInstance<SoundClip>();
88  soundClip.name = "New Sound Clip";
89 
90  AssetDatabase.AddObjectToAsset(soundClip, target);
91  AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(soundClip));
92 
93  clipsSP.InsertArrayElementAtIndex(clipsSP.arraySize);
94  SerializedProperty elementSP = clipsSP.GetArrayElementAtIndex(clipsSP.arraySize - 1);
95 
96  elementSP.objectReferenceValue = soundClip;
97  }
98  }
99 
100  void DrawList()
101  {
102  EditorGUILayout.LabelField("Sound clips", EditorStyles.boldLabel);
103 
104  update = false;
105  delete = false;
106  deleteIndex = 0;
107  updateDeleteObject = null;
108 
109  if (clipsSP.arraySize > 0)
110  clipsRL.DoLayoutList();
111  else
112  EditorGUILayout.LabelField("Currently there is no data in this container.");
113 
114  if (update)
115  {
116  SoundClip element = (SoundClip)updateDeleteObject;
117  string newName = element.name;
118 
119  AssetDatabase.SetLabels(element, new string[] { newName });
120  AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(element));
121  }
122 
123  if (delete)
124  {
125  if (clipsSP.GetArrayElementAtIndex(deleteIndex) != null)
126  clipsSP.DeleteArrayElementAtIndex(deleteIndex);
127 
128  clipsSP.DeleteArrayElementAtIndex(deleteIndex);
129  UnityEngine.Object.DestroyImmediate(updateDeleteObject, true);
130  AssetDatabase.SaveAssets();
131  AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
132  }
133 
134  }
135 
136 
137  void OnDrawElement_ClipsRL(Rect rect, int index, bool isActive, bool isFocused)
138  {
139  float height = EditorGUIUtility.singleLineHeight * 1.25f;
140  SerializedProperty elementSP = clipsSP.GetArrayElementAtIndex(index);
141  float totalLineHeight = EditorGUIUtility.singleLineHeight * 1.25f;
142 
143 
144  Rect mainLabelRect = new Rect(rect);
145  mainLabelRect.height = EditorGUIUtility.singleLineHeight;
146  mainLabelRect.y += 2;
147  EditorGUI.LabelField(mainLabelRect, elementSP.objectReferenceValue.name, EditorStyles.boldLabel);
148 
149  // active is the selected
150  if (isActive)
151  {
152  height = 7.5f * totalLineHeight;
153 
154  float moveToLeft = 15.0f;
155  float adjustedStartX = rect.x - moveToLeft;
156  float adjustedWidth = rect.width + moveToLeft;
157 
158  Rect guiRect = new Rect(adjustedStartX, rect.y + totalLineHeight, adjustedWidth, EditorGUIUtility.singleLineHeight);
159 
160  // Basic Bar
161  EditorGUI.LabelField(guiRect, "General", EditorStyles.boldLabel);
162  guiRect.y += totalLineHeight;
163 
164  float nameLabelWidth = 50.0f;
165  guiRect.width = nameLabelWidth;
166  EditorGUI.LabelField(guiRect, "Name:");
167  guiRect.x += nameLabelWidth;
168  float updateButtonWidth = 120.0f;
169  float deleteButtonWidth = 60.0f;
170  guiRect.width = adjustedWidth - nameLabelWidth - updateButtonWidth - deleteButtonWidth;
171  elementSP.objectReferenceValue.name = EditorGUI.TextField(guiRect, elementSP.objectReferenceValue.name);
172 
173  guiRect.x = rect.x + rect.width - updateButtonWidth - deleteButtonWidth;
174  guiRect.width = updateButtonWidth;
175  if (GUI.Button(guiRect, "Update File Name"))
176  {
177  update = true;
178  updateDeleteObject = elementSP.objectReferenceValue;
179  }
180 
181  guiRect.x = rect.x + rect.width - deleteButtonWidth;
182  guiRect.width = deleteButtonWidth;
183  if (GUI.Button(guiRect, "Delete"))
184  {
185  delete = true;
186  this.deleteIndex = index;
187  updateDeleteObject = elementSP.objectReferenceValue;
188  }
189 
190  guiRect.x = adjustedStartX;
191  guiRect.y += 1.5f * totalLineHeight;
192  guiRect.width = adjustedWidth;
193 
194  EditorGUI.LabelField(guiRect, "Sound Clip Data", EditorStyles.boldLabel);
195  guiRect.y += totalLineHeight;
196 
197  // Draw elemt for sound clip data
198  SerializedObject elementSO = new SerializedObject(elementSP.objectReferenceValue);
199  elementSO.Update();
200 
201  // Clip
202  EditorGUI.PropertyField(guiRect, elementSO.FindProperty(clipSPName));
203  guiRect.y += totalLineHeight;
204 
205  // Volume
206  EditorGUI.PropertyField(guiRect, elementSO.FindProperty(volumeSPName));
207  guiRect.y += totalLineHeight;
208 
209  // Pitch
210  EditorGUI.PropertyField(guiRect, elementSO.FindProperty(pitchSPName));
211 
212  elementSO.ApplyModifiedProperties();
213  }
214 
215  // Update height
216  try
217  {
218  clipsRLHeights[index] = height;
219  }
220  catch(ArgumentOutOfRangeException e)
221  {
222  Debug.LogWarning(e.Message);
223  }
224  finally
225  {
226  OnHeightsChanged_ClipsRL();
227  }
228  }
229 
230  float OnElementHeight_ClipsRL(int index)
231  {
232  Repaint();
233  float height = 0;
234 
235  try
236  {
237  height = clipsRLHeights[index];
238  }
239  catch(ArgumentOutOfRangeException e)
240  {
241  // Debug.LogWarning(e.Message);
242  }
243  finally
244  {
245  OnHeightsChanged_ClipsRL();
246  }
247 
248  return height;
249  }
250 
252  {
253  float[] floats = clipsRLHeights.ToArray();
254  Array.Resize(ref floats, clipsSP.arraySize);
255  clipsRLHeights.Clear();
256  clipsRLHeights.AddRange(floats);
257  }
258 
259  void OnDrawElementBackground_ClipsRL(Rect rect, int index, bool isActive, bool isFocused)
260  {
261  rect.x += 1;
262  rect.width -= 3;
263  rect.height = clipsRLHeights[index];
264  if (isActive)
265  GUI.DrawTexture(rect, highlightTextureRL as Texture);
266  }
267  }
268 }
void OnDrawElementBackground_ClipsRL(Rect rect, int index, bool isActive, bool isFocused)
Custom inspector for the Playlist class.
void OnDrawElement_ClipsRL(Rect rect, int index, bool isActive, bool isFocused)
This is a container ScriptableObject that holds all data required to play a AudioClip.
Definition: SoundClip.cs:11