Example #1
0
	void DrawAudioClips(SECTR_AudioCue myCue, SECTR_AudioCue srcCue)
	{
		clipFoldout = EditorGUILayout.Foldout(clipFoldout, "Audio Clips");
		if(clipFoldout)
		{
			++EditorGUI.indentLevel;
		
			bool hasClips = myCue.AudioClips.Count > 0;

#if UNITY_4_EARLY
			int lineHeight = 16;
#else
			int lineHeight = (int)EditorGUIUtility.singleLineHeight;
#endif
			int headerHeight = 25;
			int iconSize = lineHeight;

			// Column labels
			Rect headerRect = EditorGUILayout.BeginHorizontal();
			GUI.Box(headerRect, GUIContent.none);
			EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(iconSize * 2), GUILayout.MaxWidth(iconSize * 2), GUILayout.MinWidth(iconSize * 2), GUILayout.ExpandWidth(false), GUILayout.Height(headerHeight));

			string[] categories = {
				"CLIP",
				"VOLUME",
				"REMOVE",
			};
			float[] widthScales = {
				1.6f,
				0.7f,
				0.7f,
			};
			int[] widths = new int[categories.Length];
			int baseColumnWidth = (int)(headerRect.width / categories.Length);

			clipStyle.fontStyle = FontStyle.Bold;
			clipStyle.alignment = TextAnchor.MiddleCenter;
			
			int columnSum = 0;
			for(int catIndex = 0; catIndex < categories.Length; ++catIndex)
			{
				int width = (int)(widthScales[catIndex] * baseColumnWidth);
				GUI.Label(new Rect(columnSum + headerRect.x, headerRect.y, width, headerRect.height), categories[catIndex], clipStyle);
				columnSum += width;
				widths[catIndex] = width;
			}

			clipStyle.fontStyle = FontStyle.Normal;
			
			EditorGUILayout.EndHorizontal();

			Rect clipAreaRect = EditorGUILayout.BeginVertical(GUILayout.MinHeight(100));
			EditorGUILayout.Space();

			bool wasEnabled = GUI.enabled;
			GUI.enabled = false;
			GUI.Button(clipAreaRect, GUIContent.none);
			GUI.enabled = wasEnabled;

			int currentClipIndex = -1;
			int numClips = myCue.AudioClips.Count;
			bool clipProblem = false;
			bool panProblem = false;
			bool hdrProblem = false;
			int clipToRemove = -1;
			for(int clipIndex = 0; clipIndex < numClips; ++clipIndex)
			{
				SECTR_AudioCue.ClipData clipData = myCue.AudioClips[clipIndex];
				if(clipData != null && clipData.Clip != null)
				{
					AudioClip clip = clipData.Clip;

					bool reallyWasEnabled = GUI.enabled;
					GUI.enabled = true;
					Rect clipRect = EditorGUILayout.BeginHorizontal();
					if(GUILayout.Button(new GUIContent(playIcon, "Plays this AudioClip."), iconButtonStyle, GUILayout.Width(lineHeight), GUILayout.Height(lineHeight)))
					{
						SECTR_AudioSystem.Audition(clip);
					}
					GUI.enabled = reallyWasEnabled;

					int checkSize = 20;
					int columnIndex = 0;
					int columnWidth = 0;
					float rowY = clipRect.y + 1;
					columnSum = (int)clipRect.x;

					if(srcCue.Pan2D != 0 && clip.channels > 2)
					{
						panProblem = true;
					}

					if(srcCue.HDR && !clipData.HDRKeysValid())
					{
						hdrProblem = true;
					}
#if UNITY_4
					AudioImporter importer = (AudioImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(clip));
					if(importer.threeD != srcCue.Is3D)
					{
						clipProblem = true;
						clipStyle.normal.textColor = Color.red;
					}
					else
#endif
					{
						clipStyle.normal.textColor = EditorGUIUtility.isProSkin ? Color.gray : Color.black;
					}
					clipStyle.alignment = TextAnchor.MiddleLeft;

					// Name
					columnWidth = widths[columnIndex++];
					float shift = iconSize * 1.5f;
					GUI.Label(new Rect(columnSum + shift, rowY, columnWidth - shift, clipRect.height), clip.name, clipStyle);
					columnSum += columnWidth;

					// Volume
					columnWidth = widths[columnIndex++];
					int labelWidth = 40;
					float oldVolume = clipData.Volume;
					float newVolume = EditorGUI.FloatField(new Rect(columnSum - labelWidth * 0.6f + columnWidth * 0.5f, rowY, labelWidth, clipRect.height), oldVolume);
					if(newVolume != oldVolume)
					{
						SECTR_Undo.Record(myCue, "Changed Clip Volume");
						clipData.Volume = newVolume;
						EditorUtility.SetDirty(myCue);
					}
					columnSum += columnWidth;

					// Remove Button
					columnWidth = widths[columnIndex++];
					if(GUI.Button(new Rect(columnSum - checkSize * 0.5f + columnWidth * 0.5f, rowY, checkSize, clipRect.height), new GUIContent(removeIcon, "Removes AudioClip from Cue")))
					{
						clipToRemove = clipIndex;
					}
					columnSum += columnWidth;

					EditorGUILayout.EndHorizontal();

					if(Event.current.type == EventType.ContextClick && clipRect.Contains(Event.current.mousePosition))
					{
						currentClipIndex = clipIndex;
					}

					if(srcCue.HDR)
					{
						if(clipData.HDRCurve != null && clipData.HDRCurve.length > 0)
						{
							EditorGUI.BeginChangeCheck();
							EditorGUILayout.CurveField("HDR Envelope", clipData.HDRCurve);
							if(EditorGUI.EndChangeCheck())
							{
								SECTR_Undo.Record(myCue, "Changed HDR Curve");
							}
						}
						else
						{
							bool reallyReallyWasEnabled = GUI.enabled;
							GUI.enabled = false;
							EditorGUILayout.CurveField("HDR Envelope", dummyCurve);
							GUI.enabled = reallyReallyWasEnabled;
						}
					}
				}
				else
				{
					if(GUILayout.Button(new GUIContent("Remove NULL Clip", "Removes NULL audio clip reference.")))
					{
						clipToRemove = clipIndex;
					}
				}
			}

			if(clipToRemove >= 0)
			{
				SECTR_Undo.Record(myCue, "Removed Clip");
				myCue.RemoveClip(clipToRemove);
			}

			EditorGUILayout.Space();
			if(GUI.enabled)
			{
				bool reallyWasEnabled = GUI.enabled;
				GUI.enabled = false;
				clipStyle.alignment = TextAnchor.MiddleCenter;
				EditorGUILayout.LabelField("Drag in Additional Audio Clips", clipStyle);
				GUI.enabled = reallyWasEnabled;
			}
			EditorGUILayout.EndVertical();
			
			if(myCue.AudioClips.Count > 1)
			{
				DrawProperty("PlaybackMode");
			}

			wasEnabled = GUI.enabled;
			GUI.enabled = myCue.AudioClips.Count > 0;
			if(SECTR_AudioSystem.IsAuditioning())
			{
				if(GUILayout.Button(new GUIContent("Stop Audition", "Stops auditioning of this AudioCue.")))
				{
					SECTR_AudioSystem.StopAudition();
				}
			}
			else
			{
				if(GUILayout.Button(new GUIContent("Audition", "Selects and play and AudioClip from this AudioCue.")))
				{
					SECTR_AudioSystem.Audition(myCue);
				}
			}
			GUI.enabled = wasEnabled;

			if(clipProblem)
			{
				clipStyle.alignment = TextAnchor.MiddleCenter;
				clipStyle.normal.textColor = Color.red;
				GUILayout.Label("Warning: Cue and Clips have Mismatched 3D settings. Please Fix.", clipStyle);
			}
								
			if(panProblem)
			{
				clipStyle.alignment = TextAnchor.MiddleCenter;
				clipStyle.normal.textColor = Color.red;
				GUILayout.Label("Warning: Pan2D has no effect on clips with more than two channels.", clipStyle);
			}

			if(hdrProblem)
			{
				if(bakeMaster)
				{
#if UNITY_4_EARLY
					GUI.enabled = false;
					GUILayout.Button("Baking HDR Data: " + bakeMaster.Progress * 100f + "%");
					GUI.enabled = wasEnabled;
#else
					Rect controlRect = EditorGUILayout.GetControlRect();
					EditorGUI.ProgressBar(controlRect, bakeMaster.Progress, "Baking HDR Data");
#endif
				}
				else
				{
					clipStyle.alignment = TextAnchor.MiddleCenter;
					clipStyle.normal.textColor = Color.red;
					GUILayout.Label("Warning: Cue is missing some HDR data. Bake HDR Keys for higher quality sound.", clipStyle);
					if(GUILayout.Button("Bake HDR Keys"))
					{
						List<SECTR_AudioCue> bakeList = new List<SECTR_AudioCue>(1);
						bakeList.Add(myCue);
						bakeMaster = SECTR_ComputeRMS.BakeList(bakeList);
					}
				}
			}

			// Event handling
			if(Event.current.type == EventType.ContextClick && clipAreaRect.Contains(Event.current.mousePosition))
			{
				GenericMenu menu = new GenericMenu();

				if(hasClips)
				{
					if(currentClipIndex >= 0)
					{
						menu.AddItem(new GUIContent("Remove " + myCue.AudioClips[currentClipIndex].Clip.name), false, delegate() 
						{
							SECTR_Undo.Record(myCue, "Removed Clip");
							myCue.RemoveClip(currentClipIndex);
						});
					}

					menu.AddItem(new GUIContent("Clear All Clips"), false, delegate() 
					{
						myCue.ClearClips();
					});
				}
				menu.ShowAsContext();
			}
			
			if(clipAreaRect.Contains(Event.current.mousePosition))
			{
				int numDropObjects = DragAndDrop.objectReferences.Length;
				if(numDropObjects > 0)
				{
					if(Event.current.type == EventType.DragUpdated)
					{
						DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
					}
					else if(Event.current.type == EventType.DragPerform)
					{
						for(int dropIndex = 0; dropIndex < numDropObjects; ++dropIndex)
						{
							AudioClip clip = DragAndDrop.objectReferences[dropIndex] as AudioClip;
							if(clip != null)
							{
								SECTR_Undo.Record(myCue, "Add Clip");
								myCue.AddClip(clip, false);
								DragAndDrop.AcceptDrag();
							}
						}
					}
				}
			}

			--EditorGUI.indentLevel;
		}
	}
Example #2
0
	private void _HandleEvents()
	{
		if(Event.current != null)
		{
			if(!string.IsNullOrEmpty(Event.current.commandName) && Event.current.commandName == "UndoRedoPerformed")
			{
				Repaint();
				return;
			}

			if((showHierarchy && showProperties && leftSplitter.HandleEvents(this)) || (showClipList && (showHierarchy || showProperties) && bottomSplitter.HandleEvents(this)))
			{
				Repaint();
				return;
			}

#if UNITY_EDITOR_OSX
			bool heldControl = (Event.current.modifiers & EventModifiers.Command) != 0;
#else
			bool heldControl = (Event.current.modifiers & EventModifiers.Control) != 0;
#endif
			bool heldShift = (Event.current.modifiers & EventModifiers.Shift) != 0;

			switch(Event.current.type)
			{
			case EventType.MouseDown:
				if(Event.current.button == 0)
				{
					if(Event.current.mousePosition.x < leftSplitter.pos && Event.current.mousePosition.y < bottomSplitter.pos)
					{
						foreach(TreeItem item in displayedHierarchyItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								if(Event.current.clickCount > 1)
								{
									if(SECTR_VC.IsEditable(item.Path))
									{									
										_StartRenameItem(item, true);
									}
								}
								else
								{
									dragHierarchyItem = item;
								}
								break;
							}
						}
					}
					else if(Event.current.mousePosition.y > bottomSplitter.pos)
					{
						foreach(TreeItem item in displayedClipItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								if(Event.current.clickCount > 1)
								{
									if(SECTR_VC.IsEditable(item.Path))
									{									
										_StartRenameItem(item, false);
									}
								}
								else
								{
									dragClipItem = item;
								}
								break;
							}
						}
					}
				}
				break;
			case EventType.MouseUp:
				dragHierarchyItem = null;
				dragClipItem = null;
				dragHoverItem = null;

				if(selectedHierarchyItem != null && selectedHierarchyItem.Rename && !selectedHierarchyItem.WindowRect.Contains(Event.current.mousePosition))
				{
					_CancelRename(selectedHierarchyItem);
				}
				else if(selectedClipItem != null && selectedClipItem.Rename && !selectedClipItem.WindowRect.Contains(Event.current.mousePosition))
				{
					_CancelRename(selectedClipItem);
				}
				else if(Event.current.mousePosition.x < leftSplitter.pos && Event.current.mousePosition.y < bottomSplitter.pos)
				{
					lastSelectedHierarchy = true;
					TreeItem newSelection = Event.current.button == 0 ? null : selectedHierarchyItem;
					foreach(TreeItem item in displayedHierarchyItems)
					{
						if(item.WindowRect.Contains(Event.current.mousePosition))
						{
							newSelection = item;
							break;
						}
					}

					if(newSelection != selectedHierarchyItem || heldControl || heldShift)
					{
						if(newSelection == null)
						{
							selectedHierarchyItem = null;
							selectedHierarchyItems.Clear();
						}
						else if(heldControl)
						{
							if(selectedHierarchyItems.Contains(newSelection))
							{
								selectedHierarchyItems.Remove(newSelection);
								if(selectedHierarchyItems.Count > 0)
								{
									selectedHierarchyItem = selectedHierarchyItems[0];
								}
								else
								{
									selectedHierarchyItem = null;
								}
							}
							else
							{
								selectedHierarchyItems.Add(newSelection);
								selectedHierarchyItem = newSelection;
							}
						}
						else if(heldShift && selectedHierarchyItem != null)
						{
							foreach(TreeItem item in displayedHierarchyItems)
							{
								if((item.WindowRect.y >= selectedHierarchyItem.WindowRect.y && item.WindowRect.y <= newSelection.WindowRect.y) ||
								   (item.WindowRect.y <= selectedHierarchyItem.WindowRect.y && item.WindowRect.y >= newSelection.WindowRect.y))
								{
									if(!selectedHierarchyItems.Contains(item))
									{
										selectedHierarchyItems.Add(item);
									}
								}
								else
								{
									selectedHierarchyItems.Remove(item);
								}
							}
							selectedHierarchyItem = newSelection;
						}
						else
						{
							selectedHierarchyItem = newSelection;
							selectedHierarchyItems.Clear();
							selectedHierarchyItems.Add(selectedHierarchyItem);
						}
						propertyEditor = null;
						GUI.FocusControl(null);
						Repaint();
					}
				}
				else if(Event.current.mousePosition.y > bottomSplitter.pos)
				{
					lastSelectedHierarchy = false;
					TreeItem newSelection = Event.current.button == 0 ? null : selectedClipItem;
					foreach(TreeItem item in displayedClipItems)
					{
						if(item.WindowRect.Contains(Event.current.mousePosition))
						{
							newSelection = item;
							break;
						}
					}

					if(newSelection != selectedClipItem || heldControl || heldShift)
					{
						if(newSelection == null)
						{
							selectedClipItem = null;
							selectedClipItems.Clear();
						}
						else if(heldControl)
						{
							if(selectedClipItems.Contains(newSelection))
							{
								selectedClipItems.Remove(newSelection);
								if(selectedClipItems.Count > 0)
								{
									selectedClipItem = selectedClipItems[0];
								}
								else
								{
									selectedClipItem = null;
								}
							}
							else
							{
								selectedClipItems.Add(newSelection);
								selectedClipItem = newSelection;
							}
						}
						else if(heldShift && selectedClipItem != null)
						{
							foreach(TreeItem item in displayedClipItems)
							{
								if((item.WindowRect.y >= selectedClipItem.WindowRect.y && item.WindowRect.y <= newSelection.WindowRect.y) ||
								   (item.WindowRect.y <= selectedClipItem.WindowRect.y && item.WindowRect.y >= newSelection.WindowRect.y))
								{
									if(!selectedClipItems.Contains(item))
									{
										selectedClipItems.Add(item);
									}
								}
								else
								{
									selectedClipItems.Remove(item);
								}
							}
							selectedClipItem = newSelection;
						}
						else
						{
							selectedClipItem = newSelection;
							selectedClipItems.Clear();
							selectedClipItems.Add(selectedClipItem);
						}

						Repaint();
					}
				}
				break;
			case EventType.MouseDrag:
				if(Event.current.mousePosition.y > bottomSplitter.pos && dragClipItem != null)
				{
					if(!selectedClipItems.Contains(dragClipItem))
					{
						selectedClipItem = dragClipItem;
						selectedClipItems.Clear();
						selectedClipItems.Add(selectedClipItem);
					}
					DragAndDrop.PrepareStartDrag();
					int numSelected = selectedClipItems.Count;
					Object[] objects = new Object[numSelected];
					for(int selectedIndex = 0; selectedIndex < numSelected; ++selectedIndex)
					{
						objects[selectedIndex] = selectedClipItems[selectedIndex].Clip;
					}
					DragAndDrop.objectReferences = objects;
					DragAndDrop.StartDrag("Dragging " + dragClipItem.Name + " (AudioClip)");
					Event.current.Use();
				}
				else if(Event.current.mousePosition.x < leftSplitter.pos && dragHierarchyItem != null)
				{
					if(!selectedHierarchyItems.Contains(dragHierarchyItem))
					{
						selectedHierarchyItem = dragHierarchyItem;
						selectedHierarchyItems.Clear();
						selectedHierarchyItems.Add(selectedHierarchyItem);
					}
					DragAndDrop.PrepareStartDrag();
					int numSelected = selectedHierarchyItems.Count;
					Object[] objects = new Object[numSelected];
					for(int selectedIndex = 0; selectedIndex < numSelected; ++selectedIndex)
					{
						objects[selectedIndex] = selectedHierarchyItems[selectedIndex].AsObject;
					}
					DragAndDrop.objectReferences = objects;
					DragAndDrop.StartDrag("Dragging " + dragHierarchyItem.Name + " (" + objects[0].GetType() + ")");
					Event.current.Use();
				}
				break;
			case EventType.DragPerform:
			case EventType.DragUpdated:
				if(Event.current.mousePosition.x < leftSplitter.pos && Event.current.mousePosition.y < bottomSplitter.pos)
				{
					TreeItem hoverItem = null;
					Object dragObject = DragAndDrop.objectReferences[0];
					if(dragObject && dragObject.GetType() == typeof(AudioClip))
					{
						foreach(TreeItem item in displayedHierarchyItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								if(Event.current.type == EventType.DragPerform)
								{
									if(item.Cue != null && SECTR_VC.IsEditable(item.Path))
									{
										SECTR_Undo.Record(item.Cue, "Add Clip");
										foreach(TreeItem selectedItem in selectedClipItems)
										{
											if(selectedItem.Importer != null)
											{
												item.Cue.AddClip(selectedItem.Clip, false);
											}
										}
										selectedHierarchyItem = item;
										selectedHierarchyItems.Clear();
										selectedHierarchyItems.Add(selectedHierarchyItem);
										DragAndDrop.AcceptDrag();
										Repaint();
									}
									else if(item.Bus != null)
									{
										foreach(TreeItem selectedItem in selectedClipItems)
										{
											if(selectedItem.Importer != null)
											{
												TreeItem newItem = _CreateTreeItem(item, false, selectedItem.Clip.name);
												if(newItem != null)
												{
													SECTR_AudioCue cue = newItem.Cue;
#if UNITY_4
													AudioImporter importer = selectedItem.Importer;
													cue.Loops = importer.loopable;
													cue.Spatialization = importer.threeD ? SECTR_AudioCue.Spatializations.Local3D : SECTR_AudioCue.Spatializations.Simple2D;
#endif
													cue.AddClip(selectedItem.Clip, false);
													newItem.Rename = selectedClipItems.Count == 1;
												}
											}
										}
										AssetDatabase.SaveAssets();
										AssetDatabase.Refresh();
										DragAndDrop.AcceptDrag();
										Repaint();
									}
								}
								else
								{
									hoverItem = item;
									DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
								}
								break;
							}
						}
					}
					else if(dragObject && dragObject.GetType() == typeof(SECTR_AudioBus))
					{
						SECTR_AudioBus bus = ((SECTR_AudioBus)dragObject);
						foreach(TreeItem item in displayedHierarchyItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								if(item.Bus != null && bus != item.Bus && bus.Parent != item.Bus && !bus.IsAncestorOf(item.Bus) && 
									SECTR_VC.IsEditable(item.Path))
								{
									if(Event.current.type == EventType.DragPerform)
									{
										foreach(TreeItem selectedItem in selectedHierarchyItems)
										{
											if(selectedItem.Bus != null && selectedItem.Bus.Parent != item.Bus && !selectedItem.Bus.IsAncestorOf(item.Bus) &&
											   SECTR_VC.IsEditable(selectedItem.Path))
											{
												selectedItem.Bus.Parent = item.Bus;
												EditorUtility.SetDirty(selectedItem.Bus);
											}
										}
										DragAndDrop.AcceptDrag();
										Repaint();
									}
									else
									{
										hoverItem = item;
										DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
									}
								}
								break;
							}
						}
					}
					else if(dragObject && dragObject.GetType() == typeof(SECTR_AudioCue))
					{
						SECTR_AudioCue cue = ((SECTR_AudioCue)dragObject);
						foreach(TreeItem item in displayedHierarchyItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								if(item.Bus != null && item.Bus != cue.Bus && 
								   SECTR_VC.IsEditable(item.Path))
								{
									if(Event.current.type == EventType.DragPerform)
									{
										foreach(TreeItem selectedItem in selectedHierarchyItems)
										{
											if(selectedItem.Cue && selectedItem.Cue.Bus != item.Bus &&
											   SECTR_VC.IsEditable(selectedItem.Path))
											{
												selectedItem.Cue.Bus = item.Bus;
												EditorUtility.SetDirty(selectedItem.Cue);
											}
										}
										DragAndDrop.AcceptDrag();
										Repaint();
									}
									else
									{
										hoverItem = item;
										DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
									}
								}
								break;
							}
						}
					}

					if(dragHoverItem != hoverItem)
					{
						dragHoverItem = hoverItem;
						Repaint();
					}
				}
				break;
			case EventType.KeyUp:
				bool renameHierarchy = lastSelectedHierarchy && selectedHierarchyItem != null && selectedHierarchyItem.Rename;
				bool renameClip = !lastSelectedHierarchy && selectedClipItem != null && selectedClipItem.Rename;
				if(renameHierarchy || renameClip)
				{
					if(Event.current.keyCode == KeyCode.Escape)
					{
						if(renameHierarchy)
						{
							_CancelRename(selectedHierarchyItem);
						}
						else if(renameClip)
						{
							_CancelRename(selectedClipItem);
						}
					}
					else if(Event.current.keyCode == KeyCode.Return)
					{
						string newPath = "";
						bool cue = selectedHierarchyItem != null && selectedHierarchyItem.Cue != null;
						bool bus = selectedHierarchyItem != null && selectedHierarchyItem.Bus != null;
						bool importer = selectedClipItem != null && selectedClipItem.Importer != null;

						if(renameHierarchy)
						{
							newPath = selectedHierarchyItem.Path.Replace(selectedHierarchyItem.DefaultName, selectedHierarchyItem.Name);
							if(newPath == selectedHierarchyItem.Path)
							{
								_CancelRename(selectedHierarchyItem);
								return;
							}
							AssetDatabase.RenameAsset(selectedHierarchyItem.Path, selectedHierarchyItem.Name);
							SECTR_VC.WaitForVC();
							_RemoveHierarchyItem(selectedHierarchyItem);
						}
						else if(renameClip)
						{
							newPath = selectedClipItem.Path.Replace(Path.GetFileNameWithoutExtension(selectedClipItem.Path), selectedClipItem.Name);
							if(newPath == selectedClipItem.Path)
							{
								_CancelRename(selectedClipItem);
								return;
							}
							AssetDatabase.RenameAsset(selectedClipItem.Path, selectedClipItem.Name);
							SECTR_VC.WaitForVC();
							_RemoveClipItem(selectedClipItem);
						}

						TreeItem renamedItem = null;
						if(renameHierarchy && cue)
						{
							SECTR_AudioBus newBus = (SECTR_AudioBus)AssetDatabase.LoadAssetAtPath(newPath, typeof(SECTR_AudioBus));
							if(newBus)
							{
								renamedItem = new TreeItem(this, newBus, newPath);
							}
						}
						else if(renameHierarchy && bus)
						{
							SECTR_AudioCue newCue = (SECTR_AudioCue)AssetDatabase.LoadAssetAtPath(newPath, typeof(SECTR_AudioCue));
							if(newCue)
							{
								renamedItem = new TreeItem(this, newCue, newPath);
							}
						}
						else if(renameClip && importer)
						{
							AudioImporter newImporter = (AudioImporter)AssetImporter.GetAtPath(newPath);
							if(newImporter)
							{
								renamedItem = new TreeItem(newImporter, newPath, Path.GetFileName(newPath));
							}
							AudioClipFolder folder = clipItems[Path.GetDirectoryName(newPath) + "/"];
							folder.items.Add(renamedItem);
							folder.items.Sort(delegate(TreeItem A, TreeItem B) 
							{
								return string.Compare(A.DefaultName, B.DefaultName);
							});
						}
						if(renamedItem != null)
						{
							if(renameHierarchy)
							{
								selectedHierarchyItem = renamedItem;
								selectedHierarchyItems.Clear();
								selectedHierarchyItems.Add(selectedHierarchyItem);
							}
							else if(renameClip)
							{
								selectedClipItem = renamedItem;
								selectedClipItems.Clear();
								selectedClipItems.Add(selectedHierarchyItem);
							}
						}
						else
						{
							Debug.LogWarning("Unable to rename asset. Name may already be in use.");
							_RefreshAssets();
						}
						GUI.FocusControl(null);
						Repaint();
					}
				}
				else
				{
					switch(Event.current.keyCode)
					{
					case KeyCode.Return:
						if(string.IsNullOrEmpty(GUI.GetNameOfFocusedControl()))
						{
							if(lastSelectedHierarchy && selectedHierarchyItem != null && SECTR_VC.IsEditable(selectedHierarchyItem.Path))
							{
								_StartRenameItem(selectedHierarchyItem, true);
							}
							else if(!lastSelectedHierarchy && selectedClipItem != null && SECTR_VC.IsEditable(selectedClipItem.Path))
							{
								_StartRenameItem(selectedClipItem, false);
								Repaint();
							}
						}
						else if(changedAudioClip)
						{
							GUI.FocusControl(null);
							Repaint();
						}
						break;
					case KeyCode.D:
						if(heldControl)
						{
							if(lastSelectedHierarchy && selectedHierarchyItem != null)
							{
								_DuplicateSelected(selectedHierarchyItem, true);
							}
							else if(!lastSelectedHierarchy && selectedClipItem != null)
							{
								_DuplicateSelected(selectedClipItem, false);
							}
						}
						break;
					case KeyCode.Delete:
					case KeyCode.Backspace:
						if(string.IsNullOrEmpty(GUI.GetNameOfFocusedControl()))
						{
							if(lastSelectedHierarchy && selectedHierarchyItem != null && SECTR_VC.IsEditable(selectedHierarchyItem.Path))
							{
								_DeleteSelected(selectedHierarchyItem, true);
							}
							else if(!lastSelectedHierarchy && selectedClipItem != null && SECTR_VC.IsEditable(selectedClipItem.Path))
							{
								_DeleteSelected(selectedClipItem, false);
							}
						}
						break;
					case KeyCode.Escape:
						SECTR_AudioSystem.StopAudition();
						break;
					case KeyCode.Space:
						if(lastSelectedHierarchy && selectedHierarchyItem != null && selectedHierarchyItem.Cue != null)
						{
							SECTR_AudioSystem.Audition(selectedHierarchyItem.Cue);
						}
						else if(!lastSelectedHierarchy && selectedClipItem != null)
						{
							SECTR_AudioSystem.Audition(selectedClipItem.Clip);
						}
						break;
					case KeyCode.UpArrow:
					case KeyCode.DownArrow:
					case KeyCode.LeftArrow:
					case KeyCode.RightArrow:
						if(lastSelectedHierarchy && selectedHierarchyItem != null)
						{
							int numDisplayed = displayedHierarchyItems.Count;
							for(int treeIndex = 0; treeIndex < numDisplayed; ++treeIndex)
							{
								if(displayedHierarchyItems[treeIndex] == selectedHierarchyItem)
								{
									if(Event.current.keyCode == KeyCode.UpArrow && treeIndex > 0)
									{
										selectedHierarchyItem = displayedHierarchyItems[treeIndex - 1];
										if(!Event.current.shift)
										{
											selectedHierarchyItems.Clear();
										}
										if(!selectedHierarchyItems.Contains(selectedHierarchyItem))
										{
											selectedHierarchyItems.Add(selectedHierarchyItem);
										}
									}
									else if(Event.current.keyCode == KeyCode.DownArrow && treeIndex < numDisplayed - 1)
									{
										selectedHierarchyItem = displayedHierarchyItems[treeIndex + 1];
										if(!Event.current.shift)
										{
											selectedHierarchyItems.Clear();
										}
										if(!selectedHierarchyItems.Contains(selectedHierarchyItem))
										{
											selectedHierarchyItems.Add(selectedHierarchyItem);
										}
									}
									else if(Event.current.keyCode == KeyCode.RightArrow && selectedHierarchyItem.Bus != null)
									{
										selectedHierarchyItem.Expanded = true;
									}
									else if(Event.current.keyCode == KeyCode.LeftArrow && selectedHierarchyItem.Bus != null)
									{
										selectedHierarchyItem.Expanded = false;
									}
									Repaint();
									break;
								}
							}
						}
						else if(!lastSelectedHierarchy && selectedClipItem != null)
						{
							int numDisplayed = displayedClipItems.Count;
							for(int treeIndex = 0; treeIndex < numDisplayed; ++treeIndex)
							{
								if(displayedClipItems[treeIndex] == selectedClipItem)
								{
									if(Event.current.keyCode == KeyCode.UpArrow && treeIndex > 0)
									{
										selectedClipItem = displayedClipItems[treeIndex - 1];
										if(!Event.current.shift)
										{
											selectedClipItems.Clear();
										}
										if(!selectedClipItems.Contains(selectedClipItem))
										{
											selectedClipItems.Add(selectedClipItem);
										}
										if(selectedClipItem.ScrollRect.y < clipScrollPos.y)
										{
											clipScrollPos.y = selectedClipItem.ScrollRect.y;
										}
									}
									else if(Event.current.keyCode == KeyCode.DownArrow && treeIndex < numDisplayed - 1)
									{
										selectedClipItem = displayedClipItems[treeIndex + 1];
										if(!Event.current.shift)
										{
											selectedClipItems.Clear();
										}
										if(!selectedClipItems.Contains(selectedClipItem))
										{
											selectedClipItems.Add(selectedClipItem);
										}
										if(selectedClipItem.ScrollRect.y > clipScrollPos.y + clipScrollRect.height)
										{
											clipScrollPos.y = selectedClipItem.ScrollRect.y;
										}
									}
									else if(Event.current.keyCode == KeyCode.RightArrow && selectedClipItem != null)
									{
										selectedClipItem.Expanded = true;
									}
									else if(Event.current.keyCode == KeyCode.LeftArrow && selectedClipItem != null)
									{
										selectedClipItem.Expanded = false;
									}
									Repaint();
									break;
								}
							}
						}

						break;
					}
				}
				break;
			case EventType.ContextClick:

				GenericMenu menu = new GenericMenu();
				
				menu.AddItem(new GUIContent("Show Hierarchy"), showHierarchy, delegate() 
				{
					showHierarchy = !showHierarchy;
					UnityEditor.EditorPrefs.SetBool(showPrefPrefix + "Hierarchy", showHierarchy);
				});
				menu.AddItem(new GUIContent("Show Properties"), showProperties, delegate() 
				{
					showProperties = !showProperties;
					UnityEditor.EditorPrefs.SetBool(showPrefPrefix + "Properties", showProperties);
				});
				menu.AddItem(new GUIContent("Show Audio Clips"), showClipList, delegate() 
				{
					showClipList = !showClipList;
					UnityEditor.EditorPrefs.SetBool(showPrefPrefix + "ClipList", showClipList);
				});

				if(Event.current.mousePosition.x < leftSplitter.pos || Event.current.mousePosition.y > bottomSplitter.pos)
				{
					menu.AddSeparator(null);
					bool hasVC = SECTR_VC.HasVC();
					if(Event.current.mousePosition.x < leftSplitter.pos && Event.current.mousePosition.y < bottomSplitter.pos)
					{
						TreeItem cloneItem = null;
						foreach(TreeItem item in displayedHierarchyItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								cloneItem = item;
								bool editable = !hasVC || SECTR_VC.IsEditable(item.Path);

								if(hasVC)
								{
									if(!editable)
									{
										menu.AddItem(new GUIContent("Check Out"), false, delegate() 
										{
											_CheckoutSelected(item, true);
										});
									}
									else
									{
										menu.AddItem(new GUIContent("Revert"), false, delegate()
										{
											_RevertSelected(item, true);
										});
									}
								}
								
								menu.AddItem(new GUIContent("Show In Project"), false, delegate()
								{
									if(item.Cue != null) Selection.activeObject = item.Cue;
									if(item.Bus != null) Selection.activeObject = item.Bus;
									EditorUtility.FocusProjectWindow();
								});
								menu.AddSeparator("");

								menu.AddItem(new GUIContent("Duplicate"), false, delegate()
								{
									_DuplicateSelected(item, true);
								});

								if(editable)
								{
									menu.AddItem(new GUIContent("Rename"), false, delegate() 
									{
										_StartRenameItem(item, true);
									});

									menu.AddItem(new GUIContent("Delete"), false, delegate() 
									{
										_DeleteSelected(item, true);
									});
								}
								else
								{
									menu.AddSeparator("Rename");
									menu.AddSeparator("Delete");
								}

								menu.AddSeparator(null);
								break;
							}
						}

						menu.AddItem(new GUIContent("Create New Bus"), false, delegate() 
						{
							_CreateTreeItem(cloneItem, true, null);
							Repaint();
						});
						menu.AddItem(new GUIContent("Create New Cue"), false, delegate() 
						{
							_CreateTreeItem(cloneItem, false, null);
							Repaint();
						});
					}
					else if(Event.current.mousePosition.y > bottomSplitter.pos)
					{
						foreach(TreeItem item in displayedClipItems)
						{
							if(item.WindowRect.Contains(Event.current.mousePosition))
							{
								bool editable = !hasVC || SECTR_VC.IsEditable(item.Path);
								// Project Items
								if(SECTR_VC.HasVC())
								{
									if(!editable)
									{
										menu.AddItem(new GUIContent("Check Out"), false, delegate()
										{
											_CheckoutSelected(item, false);
										});
									}
									else
									{
										menu.AddItem(new GUIContent("Revert"), false, delegate()
										{
											_RevertSelected(item, false);
										});
									}
								}
								menu.AddItem(new GUIContent("Show In Project"), false, delegate()
								{
									Selection.activeObject = item.Clip;
									EditorUtility.FocusProjectWindow();
								});
								menu.AddSeparator("");

								menu.AddItem(new GUIContent("Duplicate"), false, delegate()
								{
									_DuplicateSelected(item, false);
								});
								
								if(editable)
								{
									menu.AddItem(new GUIContent("Rename"), false, delegate() 
									{
										_StartRenameItem(item, false);
									});
									menu.AddItem(new GUIContent("Delete"), false, delegate() 
									{
										_DeleteSelected(item, false);
									});
								}
								else
								{
									menu.AddSeparator("Rename");
									menu.AddSeparator("Delete");
								}

								menu.AddSeparator("");

								// Creation Items
								if(selectedHierarchyItem != null && selectedHierarchyItem.Cue != null && 
								   !selectedHierarchyItem.Cue.HasClip(item.Clip))
								{
									menu.AddItem(new GUIContent("Add Selected to Cue"), false, delegate()
									{
										SECTR_Undo.Record(selectedHierarchyItem.Cue, "Add Clips");
										foreach(TreeItem selectedItem in selectedClipItems)
										{
											selectedHierarchyItem.Cue.AddClip(selectedItem.Clip, false);
										}
										Repaint();
									});
								}
								else
								{
									menu.AddSeparator("Add Clip to Selected Cue");
								}
								menu.AddItem(new GUIContent("Create Cues from Selected"), false, delegate() 
								{
									foreach(TreeItem selectedItem in selectedClipItems)
									{
										TreeItem newItem = _CreateTreeItem(selectedHierarchyItem, false, selectedItem.Clip.name);
										if(newItem != null)
										{
											newItem.Rename = selectedClipItems.Count == 1;
											SECTR_AudioCue cue = newItem.Cue;
#if UNITY_4_0
											AudioImporter importer = (AudioImporter)AssetImporter.GetAtPath(selectedItem.Path);
											cue.Spatialization = importer.threeD ? SECTR_AudioCue.Spatializations.Local3D : SECTR_AudioCue.Spatializations.Simple2D;
											cue.Loops = importer.loopable;
#endif
											cue.AddClip(selectedItem.Clip, false);
										}
									}
									Repaint();
								});
								menu.AddSeparator("");
								break;
							}
						}

						menu.AddItem(new GUIContent("Show Advanced Properties"), showFullClipDetails, delegate()
						{
							showFullClipDetails = !showFullClipDetails;
							UnityEditor.EditorPrefs.SetBool(fullDetailsPref, showFullClipDetails);
							Repaint();
						});

						menu.AddItem(new GUIContent("Close All Folders"), false, delegate()
						{
							foreach(string path in clipItems.Keys)
							{
								clipItems[path].expanded = false;
								UnityEditor.EditorPrefs.SetBool(expandedPrefPrefix + path, false);
							}
							Repaint();
						});
					}
				}

				// Items in all menus.
				menu.AddSeparator(null);
				menu.AddItem(new GUIContent("Bake All HDR Keys"), false, delegate() 
				{
					List<string> paths = new List<string>();
					List<string> extensions = new List<string>()
					{
						".asset",
					};
					bakeMaster = SECTR_ComputeRMS.BakeList(SECTR_Asset.GetAll<SECTR_AudioCue>(audioRootPath, extensions, ref paths, false));
				});
				menu.AddSeparator(null);
				menu.AddItem(new GUIContent("Refresh Assets"), false, delegate() 
				{
					_RefreshAssets();
				});
				menu.AddSeparator(null);
				menu.AddItem(new GUIContent("Change Audio Root"), false, delegate() 
				{
					_SelectAudioRoot();
					_RefreshAssets();
				});
				menu.ShowAsContext();
				break;
			}

		}
	}