first commit
This commit is contained in:
295
Assets/AVProVideo/Editor/Scripts/RecentMenu.cs
Normal file
295
Assets/AVProVideo/Editor/Scripts/RecentMenu.cs
Normal file
@@ -0,0 +1,295 @@
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user