295 lines
10 KiB
C#
Executable File
295 lines
10 KiB
C#
Executable File
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"));
|
|
}
|
|
}
|
|
}
|
|
} |