| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 | using UnityEngine;using UnityEditor;using System.Collections.Generic;//-----------------------------------------------------------------------------// Copyright 2015-2021 RenderHeads Ltd.  All rights reserved.//-----------------------------------------------------------------------------namespace RenderHeads.Media.AVProVideo.Editor{	/// <summary>	/// </summary>	public class RecentMenu	{		public static void Create(SerializedProperty propPath, SerializedProperty propMediaSource, string fileExtensions, bool autoLoadMedia, int mediaReferencePickerId = -1)		{			RecentItems.Load();			RecentMenu menu = new RecentMenu();			menu.FileBrowseButton(propPath, propMediaSource, fileExtensions, autoLoadMedia, mediaReferencePickerId);		}		private void FileBrowseButton(SerializedProperty propPath, SerializedProperty propMediaSource, string fileExtensions, bool autoLoadMedia, int mediaReferencePickerId = -1)		{			GenericMenu toolsMenu = new GenericMenu();			if (mediaReferencePickerId >= 0)			{				toolsMenu.AddItem(new GUIContent("Media References..."), false, Callback_BrowseMediaReferences, (object)mediaReferencePickerId);			}			toolsMenu.AddItem(new GUIContent("Browse..."), false, Callback_Browse, new BrowseData(propPath, propMediaSource, fileExtensions, autoLoadMedia));			CreateMenu_StreamingAssets(toolsMenu, "StreamingAssets/", propPath, propMediaSource, autoLoadMedia);			CreateMenu_RecentFiles(toolsMenu, RecentItems.Files, "Recent Files/" , propPath, propMediaSource, autoLoadMedia);			CreateMenu_RecentUrls(toolsMenu, RecentItems.Urls, "Recent URLs/", propPath, propMediaSource, autoLoadMedia);			toolsMenu.ShowAsContext();		}		private struct RecentMenuItemData		{			public RecentMenuItemData(string path, SerializedProperty propPath, SerializedProperty propMediaSource, bool autoLoadMedia)			{				this.path = path;				this.propPath = propPath;				this.propMediaSource = propMediaSource;				this.autoLoadMedia = autoLoadMedia;			}			public string path;			public bool autoLoadMedia;			public SerializedProperty propPath;			public SerializedProperty propMediaSource;		}		private void Callback_Select(object obj)		{			RecentMenuItemData data = (RecentMenuItemData)obj;			// Move it to the top of the list			RecentItems.Add(data.path);			// Resolve to relative path			MediaPath mediaPath = EditorHelper.GetMediaPathFromFullPath(data.path);			SerializedProperty propMediaPath = data.propPath.FindPropertyRelative("_path");			SerializedProperty propMediaPathType = data.propPath.FindPropertyRelative("_pathType");			// Assign to properties			propMediaPath.stringValue = mediaPath.Path;			propMediaPathType.enumValueIndex = (int)mediaPath.PathType;			if (data.propMediaSource != null)			{				data.propMediaSource.enumValueIndex = (int)MediaSource.Path;			}			// Mark as modified			data.propPath.serializedObject.ApplyModifiedProperties();			foreach (Object o in data.propPath.serializedObject.targetObjects)			{				EditorUtility.SetDirty(o);			}			if (data.autoLoadMedia)			{				MediaPlayer mediaPlayer = (MediaPlayer)data.propPath.serializedObject.targetObject;				if (mediaPlayer != null)				{					mediaPlayer.OpenMedia(mediaPlayer.MediaPath, autoPlay:true);				}			}		}		private void Callback_ClearList(object obj)		{			((List<string>)obj).Clear();			RecentItems.Save();		}		private void Callback_ClearMissingFiles()		{			RecentItems.ClearMissingFiles();			RecentItems.Save();		}		private struct BrowseData		{			public BrowseData(SerializedProperty propPath, SerializedProperty propMediaSource, string extensions, bool autoLoadMedia)			{				this.extensions = extensions;				this.propPath = propPath;				this.propMediaSource = propMediaSource;				this.autoLoadMedia = autoLoadMedia;			}			public bool autoLoadMedia;			public string extensions;			public SerializedProperty propPath;			public SerializedProperty propMediaSource;		}		private void Callback_BrowseMediaReferences(object obj)		{			int controlID = (int)obj;			EditorGUIUtility.ShowObjectPicker<MediaReference>(null, false, "", controlID);		}		private void Callback_Browse(object obj)		{			BrowseData data = (BrowseData)obj;			SerializedProperty propFilePath = data.propPath.FindPropertyRelative("_path");			SerializedProperty propFilePathType = data.propPath.FindPropertyRelative("_pathType");			string startFolder = EditorHelper.GetBrowsableFolder(propFilePath.stringValue, (MediaPathType)propFilePathType.enumValueIndex);			string videoPath = propFilePath.stringValue;			string fullPath = string.Empty;			MediaPath mediaPath = new MediaPath();			if (EditorHelper.OpenMediaFileDialog(startFolder, ref mediaPath, ref fullPath, data.extensions))			{				// Assign to properties				propFilePath.stringValue = mediaPath.Path;				propFilePathType.enumValueIndex = (int)mediaPath.PathType;				if (data.propMediaSource != null) data.propMediaSource.enumValueIndex = (int)MediaSource.Path;				// Mark as modified				data.propPath.serializedObject.ApplyModifiedProperties();				foreach (Object o in data.propPath.serializedObject.targetObjects)				{					EditorUtility.SetDirty(o);				}				if (data.autoLoadMedia)				{					MediaPlayer mediaPlayer = (MediaPlayer)data.propPath.serializedObject.targetObject;					if (mediaPlayer != null)					{						mediaPlayer.OpenMedia(mediaPlayer.MediaPath, autoPlay:true);					}				}				RecentItems.Add(fullPath);			}		}		private void CreateMenu_RecentFiles(GenericMenu menu, List<string> items, string prefix, SerializedProperty propPath, SerializedProperty propMediaSource, bool autoLoadMedia)		{			int missingCount = 0;			for (int i = 0; i < items.Count; i++)			{				string path = items[i];				// Slashes in path must be replaced as they cause the menu to create submenuts				string itemName = ReplaceSlashes(path);				// TODO: shorten if itemName too long				if (System.IO.File.Exists(path))				{					menu.AddItem(new GUIContent(prefix + itemName), false, Callback_Select, new RecentMenuItemData(path, propPath, propMediaSource, autoLoadMedia));				}				else				{					menu.AddDisabledItem(new GUIContent(prefix + itemName));					missingCount++;				}			}			if (items.Count > 0)			{				menu.AddSeparator(prefix + "");				menu.AddItem(new GUIContent(prefix + "Clear"), false, Callback_ClearList, items);				if (missingCount > 0)				{					menu.AddItem(new GUIContent(prefix + "Clear Missing (" + missingCount + ")"), false, Callback_ClearMissingFiles);				}			}			else			{				menu.AddDisabledItem(new GUIContent(prefix + "No recent files yet"));			}		}		private void CreateMenu_RecentUrls(GenericMenu menu, List<string> items, string prefix, SerializedProperty propPath, SerializedProperty propMediaSource, bool autoLoadMedia)		{			for (int i = 0; i < items.Count; i++)			{				string path = items[i];				// Slashes in path must be replaced as they cause the menu to create submenuts				string itemName = ReplaceSlashes(path);				// TODO: shorten if itemName too long				menu.AddItem(new GUIContent(prefix + itemName), false, Callback_Select, new RecentMenuItemData(path, propPath, propMediaSource, autoLoadMedia));			}			if (items.Count > 0)			{				menu.AddSeparator(prefix + "");				menu.AddItem(new GUIContent(prefix + "Clear"), false, Callback_ClearList, items);			}			else			{				menu.AddDisabledItem(new GUIContent(prefix + "No recent URLs yet"));			}		}		private static string ReplaceSlashes(string text)		{			string slashReplacement = "\u2215";#if UNITY_EDITOR_WIN			// Special replacement for "//" in URLS so they aren't spaced too far apart			text = text.Replace("//", " \u2215 \u2215 ");			// On Windows we have to add extra spaces so it doesn't look squashed together			slashReplacement = " \u2215 ";#endif			text = text.Replace("/", slashReplacement);//.Replace("\\", slashReplacement);			// Unity will place text after " _" on the right of the menu, so we replace it so this doesn't happen			text = text.Replace(" _", "_");			return text;		}		private static List<string> FindMediaFilesInStreamingAssetsFolder()		{			List<string> files = new List<string>();			if (System.IO.Directory.Exists(Application.streamingAssetsPath))			{				string[] allFiles = System.IO.Directory.GetFiles(Application.streamingAssetsPath, "*", System.IO.SearchOption.AllDirectories);				if (allFiles != null && allFiles.Length > 0)				{					// Filter by type					for (int i = 0; i < allFiles.Length; i++)					{						string file = allFiles[i];						bool remove = false;						if (file.EndsWith(".meta", System.StringComparison.InvariantCultureIgnoreCase))						{							remove = true;						}#if UNITY_EDITOR_OSX						remove = remove || file.EndsWith(".DS_Store");#endif						if (!remove)						{#if UNITY_EDITOR_WIN							// Using Directory.GetFiles returns paths with \ in so correct this to be /							file = file.Replace("\\", "/");#endif							files.Add(file);						}					}				}			}			return files;		}		private void CreateMenu_StreamingAssets(GenericMenu menu, string prefix, SerializedProperty propPath, SerializedProperty propMediaSource, bool autoLoadMedia)		{			List<string> files = FindMediaFilesInStreamingAssetsFolder();			if (files.Count > 0)			{				for (int i = 0; i < files.Count; i++)				{					string path = files[i];					if (System.IO.File.Exists(path))					{						string itemName = path.Replace(Application.streamingAssetsPath, "");						if (itemName.StartsWith("/") || itemName.StartsWith("\\"))						{							itemName = itemName.Remove(0, 1);						}						itemName = itemName.Replace("\\", "/");						menu.AddItem(new GUIContent(prefix + itemName), false, Callback_Select, new RecentMenuItemData(path, propPath, propMediaSource, autoLoadMedia));					}				}			}			else			{				menu.AddDisabledItem(new GUIContent(prefix + "StreamingAssets folder missing or contains no files"));			}		}	}}
 |