@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 163546d147384b941b46466505aa9d68 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 15d05434831483c41b2a06cb9a59fed9 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,191 @@ | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
using SimpleJSON; | |||||
using SFB; | |||||
using System.IO; | |||||
public class JsonEditorWindow : EditorWindow | |||||
{ | |||||
public string RawJson = ""; | |||||
public string OldJson = ""; | |||||
public JSONNode jsonRoot; | |||||
private Vector2 scrollpos; | |||||
private Dictionary<JSONNode, bool> FoldHash; | |||||
private bool isFile = false; | |||||
private string FilePath; | |||||
// Add menu named "My Window" to the Window menu | |||||
[MenuItem("Tools/Editor Add On/Json Editor")] | |||||
public static void Init() | |||||
{ | |||||
// Get existing open window or if none, make a new one: | |||||
JsonEditorWindow window = (JsonEditorWindow)EditorWindow.GetWindow(typeof(JsonEditorWindow)); | |||||
window.Initialise(""); | |||||
window.Show(); | |||||
} | |||||
public static void Init(string json) | |||||
{ | |||||
// Get existing open window or if none, make a new one: | |||||
JsonEditorWindow window = (JsonEditorWindow)EditorWindow.GetWindow(typeof(JsonEditorWindow)); | |||||
window.Initialise(json); | |||||
window.Show(); | |||||
} | |||||
private void Initialise(string json = "") | |||||
{ | |||||
if (!string.IsNullOrEmpty(json)) | |||||
RawJson = json; | |||||
} | |||||
public void OnGUI() | |||||
{ | |||||
inputGUI(); | |||||
JsonGUI(); | |||||
} | |||||
private void inputGUI() | |||||
{ | |||||
EditorGUILayout.BeginHorizontal(); | |||||
if (!isFile) | |||||
{ | |||||
if (GUILayout.Button("Open File",GUILayout.Width(80))) | |||||
{ | |||||
FilePath = StandaloneFileBrowser.OpenFilePanel("Open Location File", FilePath, "txt", false)[0]; | |||||
if (File.Exists(FilePath)) | |||||
{ | |||||
RawJson = File.ReadAllText(FilePath); | |||||
isFile = true; | |||||
} | |||||
else | |||||
{ | |||||
RawJson = null; | |||||
isFile = false; | |||||
} | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (GUILayout.Button("Clear", GUILayout.Width(80))) | |||||
{ | |||||
RawJson = null; | |||||
isFile = false; | |||||
} | |||||
} | |||||
if (!isFile) | |||||
{ | |||||
RawJson = EditorGUILayout.TextField(RawJson); | |||||
} | |||||
else | |||||
{ | |||||
EditorGUILayout.LabelField(Path.GetFileName(FilePath)); | |||||
} | |||||
EditorGUILayout.EndHorizontal(); | |||||
if (OldJson == RawJson) | |||||
return; | |||||
OldJson = RawJson; | |||||
try | |||||
{ | |||||
jsonRoot = JSON.Parse(RawJson); | |||||
FoldHash = new Dictionary<JSONNode, bool>(); | |||||
} | |||||
catch | |||||
{ | |||||
Debug.LogWarning("Can not parse Json string"); | |||||
jsonRoot = null; | |||||
} | |||||
} | |||||
private void JsonGUI() | |||||
{ | |||||
scrollpos = GUILayout.BeginScrollView(scrollpos); | |||||
DrawNode(jsonRoot); | |||||
GUILayout.EndScrollView(); | |||||
if (jsonRoot != null) | |||||
{ | |||||
RawJson = jsonRoot.ToString(); | |||||
OldJson = jsonRoot.ToString(); | |||||
} | |||||
} | |||||
private void DrawJsonObject(JSONNode node,string key) | |||||
{ | |||||
if (!FoldHash.ContainsKey(node)) | |||||
FoldHash.Add(node, false); | |||||
FoldHash[node] = EditorGUILayout.Foldout(FoldHash[node], key); | |||||
if (!FoldHash[node]) | |||||
return; | |||||
foreach (KeyValuePair<string, JSONNode> child in node) | |||||
{ | |||||
DrawNode(child.Value,child.Key); | |||||
} | |||||
} | |||||
private void DrawJsonArray(JSONNode node, string key) | |||||
{ | |||||
if (!FoldHash.ContainsKey(node)) | |||||
FoldHash.Add(node, false); | |||||
FoldHash[node] = EditorGUILayout.Foldout(FoldHash[node], key); | |||||
if (!FoldHash[node]) | |||||
return; | |||||
foreach (JSONNode child in node) | |||||
DrawNode(child); | |||||
} | |||||
private void DrawNode(JSONNode node,string key = "") | |||||
{ | |||||
if (node == null) return; | |||||
EditorGUI.indentLevel++; | |||||
switch (node.Tag) | |||||
{ | |||||
case JSONNodeType.Object: | |||||
DrawJsonObject(node,key); | |||||
break; | |||||
case JSONNodeType.Array: | |||||
DrawJsonArray(node,key); | |||||
break; | |||||
default: | |||||
EditorGUILayout.BeginHorizontal(); | |||||
node.Value = EditorGUILayout.TextField(key,node.Value); | |||||
EditorGUILayout.EndHorizontal(); | |||||
break; | |||||
} | |||||
EditorGUI.indentLevel--; | |||||
} | |||||
private void DebugNode(JSONNode node) | |||||
{ | |||||
EditorGUILayout.TextArea(node.ToString(1)); | |||||
} | |||||
} |
@ -0,0 +1,11 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 017756f271c30ba43b71d59b3d79b11b | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: f183afe0cb678eb44b8f5695e56f6efb | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: bf8e1b4a99cdf864b9115839a367c306 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,21 @@ | |||||
The MIT License (MIT) | |||||
Copyright (c) 2012-2017 Markus Göbel (Bunny83) | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE. |
@ -0,0 +1,7 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 62836419310492541ace26572f0db5c8 | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,7 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ba25a3b339332594d9a93bae2ae511fc | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,11 @@ | |||||
fileFormatVersion: 2 | |||||
guid: cb81df6cab146cb40a0ef2e57844fba8 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,297 @@ | |||||
//#define USE_SharpZipLib | |||||
/* * * * * | |||||
* This is an extension of the SimpleJSON framework to provide methods to | |||||
* serialize a JSON object tree into a compact binary format. Optionally the | |||||
* binary stream can be compressed with the SharpZipLib when using the define | |||||
* "USE_SharpZipLib" | |||||
* | |||||
* Those methods where originally part of the framework but since it's rarely | |||||
* used I've extracted this part into this seperate module file. | |||||
* | |||||
* You can use the define "SimpleJSON_ExcludeBinary" to selectively disable | |||||
* this extension without the need to remove the file from the project. | |||||
* | |||||
* | |||||
* The MIT License (MIT) | |||||
* | |||||
* Copyright (c) 2012-2017 Markus Göbel (Bunny83) | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
* of this software and associated documentation files (the "Software"), to deal | |||||
* in the Software without restriction, including without limitation the rights | |||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
* copies of the Software, and to permit persons to whom the Software is | |||||
* furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice shall be included in all | |||||
* copies or substantial portions of the Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
* SOFTWARE. | |||||
* | |||||
* * * * */ | |||||
using System; | |||||
namespace SimpleJSON | |||||
{ | |||||
#if !SimpleJSON_ExcludeBinary | |||||
public abstract partial class JSONNode | |||||
{ | |||||
public abstract void SerializeBinary(System.IO.BinaryWriter aWriter); | |||||
public void SaveToBinaryStream(System.IO.Stream aData) | |||||
{ | |||||
var W = new System.IO.BinaryWriter(aData); | |||||
SerializeBinary(W); | |||||
} | |||||
#if USE_SharpZipLib | |||||
public void SaveToCompressedStream(System.IO.Stream aData) | |||||
{ | |||||
using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData)) | |||||
{ | |||||
gzipOut.IsStreamOwner = false; | |||||
SaveToBinaryStream(gzipOut); | |||||
gzipOut.Close(); | |||||
} | |||||
} | |||||
public void SaveToCompressedFile(string aFileName) | |||||
{ | |||||
System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName); | |||||
using(var F = System.IO.File.OpenWrite(aFileName)) | |||||
{ | |||||
SaveToCompressedStream(F); | |||||
} | |||||
} | |||||
public string SaveToCompressedBase64() | |||||
{ | |||||
using (var stream = new System.IO.MemoryStream()) | |||||
{ | |||||
SaveToCompressedStream(stream); | |||||
stream.Position = 0; | |||||
return System.Convert.ToBase64String(stream.ToArray()); | |||||
} | |||||
} | |||||
#else | |||||
public void SaveToCompressedStream(System.IO.Stream aData) | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
public void SaveToCompressedFile(string aFileName) | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
public string SaveToCompressedBase64() | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
#endif | |||||
public void SaveToBinaryFile(string aFileName) | |||||
{ | |||||
System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName); | |||||
using (var F = System.IO.File.OpenWrite(aFileName)) | |||||
{ | |||||
SaveToBinaryStream(F); | |||||
} | |||||
} | |||||
public string SaveToBinaryBase64() | |||||
{ | |||||
using (var stream = new System.IO.MemoryStream()) | |||||
{ | |||||
SaveToBinaryStream(stream); | |||||
stream.Position = 0; | |||||
return System.Convert.ToBase64String(stream.ToArray()); | |||||
} | |||||
} | |||||
public static JSONNode DeserializeBinary(System.IO.BinaryReader aReader) | |||||
{ | |||||
JSONNodeType type = (JSONNodeType)aReader.ReadByte(); | |||||
switch (type) | |||||
{ | |||||
case JSONNodeType.Array: | |||||
{ | |||||
int count = aReader.ReadInt32(); | |||||
JSONArray tmp = new JSONArray(); | |||||
for (int i = 0; i < count; i++) | |||||
tmp.Add(DeserializeBinary(aReader)); | |||||
return tmp; | |||||
} | |||||
case JSONNodeType.Object: | |||||
{ | |||||
int count = aReader.ReadInt32(); | |||||
JSONObject tmp = new JSONObject(); | |||||
for (int i = 0; i < count; i++) | |||||
{ | |||||
string key = aReader.ReadString(); | |||||
var val = DeserializeBinary(aReader); | |||||
tmp.Add(key, val); | |||||
} | |||||
return tmp; | |||||
} | |||||
case JSONNodeType.String: | |||||
{ | |||||
return new JSONString(aReader.ReadString()); | |||||
} | |||||
case JSONNodeType.Number: | |||||
{ | |||||
return new JSONNumber(aReader.ReadDouble()); | |||||
} | |||||
case JSONNodeType.Boolean: | |||||
{ | |||||
return new JSONBool(aReader.ReadBoolean()); | |||||
} | |||||
case JSONNodeType.NullValue: | |||||
{ | |||||
return JSONNull.CreateOrGet(); | |||||
} | |||||
default: | |||||
{ | |||||
throw new Exception("Error deserializing JSON. Unknown tag: " + type); | |||||
} | |||||
} | |||||
} | |||||
#if USE_SharpZipLib | |||||
public static JSONNode LoadFromCompressedStream(System.IO.Stream aData) | |||||
{ | |||||
var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData); | |||||
return LoadFromStream(zin); | |||||
} | |||||
public static JSONNode LoadFromCompressedFile(string aFileName) | |||||
{ | |||||
using(var F = System.IO.File.OpenRead(aFileName)) | |||||
{ | |||||
return LoadFromCompressedStream(F); | |||||
} | |||||
} | |||||
public static JSONNode LoadFromCompressedBase64(string aBase64) | |||||
{ | |||||
var tmp = System.Convert.FromBase64String(aBase64); | |||||
var stream = new System.IO.MemoryStream(tmp); | |||||
stream.Position = 0; | |||||
return LoadFromCompressedStream(stream); | |||||
} | |||||
#else | |||||
public static JSONNode LoadFromCompressedFile(string aFileName) | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
public static JSONNode LoadFromCompressedStream(System.IO.Stream aData) | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
public static JSONNode LoadFromCompressedBase64(string aBase64) | |||||
{ | |||||
throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); | |||||
} | |||||
#endif | |||||
public static JSONNode LoadFromBinaryStream(System.IO.Stream aData) | |||||
{ | |||||
using (var R = new System.IO.BinaryReader(aData)) | |||||
{ | |||||
return DeserializeBinary(R); | |||||
} | |||||
} | |||||
public static JSONNode LoadFromBinaryFile(string aFileName) | |||||
{ | |||||
using (var F = System.IO.File.OpenRead(aFileName)) | |||||
{ | |||||
return LoadFromBinaryStream(F); | |||||
} | |||||
} | |||||
public static JSONNode LoadFromBinaryBase64(string aBase64) | |||||
{ | |||||
var tmp = System.Convert.FromBase64String(aBase64); | |||||
var stream = new System.IO.MemoryStream(tmp); | |||||
stream.Position = 0; | |||||
return LoadFromBinaryStream(stream); | |||||
} | |||||
} | |||||
public partial class JSONArray : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.Array); | |||||
aWriter.Write(m_List.Count); | |||||
for (int i = 0; i < m_List.Count; i++) | |||||
{ | |||||
m_List[i].SerializeBinary(aWriter); | |||||
} | |||||
} | |||||
} | |||||
public partial class JSONObject : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.Object); | |||||
aWriter.Write(m_Dict.Count); | |||||
foreach (string K in m_Dict.Keys) | |||||
{ | |||||
aWriter.Write(K); | |||||
m_Dict[K].SerializeBinary(aWriter); | |||||
} | |||||
} | |||||
} | |||||
public partial class JSONString : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.String); | |||||
aWriter.Write(m_Data); | |||||
} | |||||
} | |||||
public partial class JSONNumber : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.Number); | |||||
aWriter.Write(m_Data); | |||||
} | |||||
} | |||||
public partial class JSONBool : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.Boolean); | |||||
aWriter.Write(m_Data); | |||||
} | |||||
} | |||||
public partial class JSONNull : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
aWriter.Write((byte)JSONNodeType.NullValue); | |||||
} | |||||
} | |||||
internal partial class JSONLazyCreator : JSONNode | |||||
{ | |||||
public override void SerializeBinary(System.IO.BinaryWriter aWriter) | |||||
{ | |||||
} | |||||
} | |||||
#endif | |||||
} |
@ -0,0 +1,11 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 6b7c9134b21d6114f8b65e86ad5dc09b | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,369 @@ | |||||
#region License and information | |||||
/* * * * * | |||||
* | |||||
* Unity extension for the SimpleJSON framework. It does only work together with | |||||
* the SimpleJSON.cs | |||||
* It provides several helpers and conversion operators to serialize/deserialize | |||||
* common Unity types such as Vector2/3/4, Rect, RectOffset, Quaternion and | |||||
* Matrix4x4 as JSONObject or JSONArray. | |||||
* This extension will add 3 static settings to the JSONNode class: | |||||
* ( VectorContainerType, QuaternionContainerType, RectContainerType ) which | |||||
* control what node type should be used for serializing the given type. So a | |||||
* Vector3 as array would look like [12,32,24] and {"x":12, "y":32, "z":24} as | |||||
* object. | |||||
* | |||||
* | |||||
* The MIT License (MIT) | |||||
* | |||||
* Copyright (c) 2012-2017 Markus Göbel (Bunny83) | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
* of this software and associated documentation files (the "Software"), to deal | |||||
* in the Software without restriction, including without limitation the rights | |||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
* copies of the Software, and to permit persons to whom the Software is | |||||
* furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice shall be included in all | |||||
* copies or substantial portions of the Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
* SOFTWARE. | |||||
* | |||||
* * * * */ | |||||
#endregion License and information | |||||
using UnityEngine; | |||||
namespace SimpleJSON | |||||
{ | |||||
public enum JSONContainerType { Array, Object } | |||||
public partial class JSONNode | |||||
{ | |||||
public static JSONContainerType VectorContainerType = JSONContainerType.Array; | |||||
public static JSONContainerType QuaternionContainerType = JSONContainerType.Array; | |||||
public static JSONContainerType RectContainerType = JSONContainerType.Array; | |||||
private static JSONNode GetContainer(JSONContainerType aType) | |||||
{ | |||||
if (aType == JSONContainerType.Array) | |||||
return new JSONArray(); | |||||
return new JSONObject(); | |||||
} | |||||
#region implicit conversion operators | |||||
public static implicit operator JSONNode(Vector2 aVec) | |||||
{ | |||||
JSONNode n = GetContainer(VectorContainerType); | |||||
n.WriteVector2(aVec); | |||||
return n; | |||||
} | |||||
public static implicit operator JSONNode(Vector3 aVec) | |||||
{ | |||||
JSONNode n = GetContainer(VectorContainerType); | |||||
n.WriteVector3(aVec); | |||||
return n; | |||||
} | |||||
public static implicit operator JSONNode(Vector4 aVec) | |||||
{ | |||||
JSONNode n = GetContainer(VectorContainerType); | |||||
n.WriteVector4(aVec); | |||||
return n; | |||||
} | |||||
public static implicit operator JSONNode(Quaternion aRot) | |||||
{ | |||||
JSONNode n = GetContainer(QuaternionContainerType); | |||||
n.WriteQuaternion(aRot); | |||||
return n; | |||||
} | |||||
public static implicit operator JSONNode(Rect aRect) | |||||
{ | |||||
JSONNode n = GetContainer(RectContainerType); | |||||
n.WriteRect(aRect); | |||||
return n; | |||||
} | |||||
public static implicit operator JSONNode(RectOffset aRect) | |||||
{ | |||||
JSONNode n = GetContainer(RectContainerType); | |||||
n.WriteRectOffset(aRect); | |||||
return n; | |||||
} | |||||
public static implicit operator Vector2(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadVector2(); | |||||
} | |||||
public static implicit operator Vector3(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadVector3(); | |||||
} | |||||
public static implicit operator Vector4(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadVector4(); | |||||
} | |||||
public static implicit operator Quaternion(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadQuaternion(); | |||||
} | |||||
public static implicit operator Rect(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadRect(); | |||||
} | |||||
public static implicit operator RectOffset(JSONNode aNode) | |||||
{ | |||||
return aNode.ReadRectOffset(); | |||||
} | |||||
#endregion implicit conversion operators | |||||
#region Vector2 | |||||
public Vector2 ReadVector2(Vector2 aDefault) | |||||
{ | |||||
if (IsObject) | |||||
return new Vector2(this["x"].AsFloat, this["y"].AsFloat); | |||||
if (IsArray) | |||||
return new Vector2(this[0].AsFloat, this[1].AsFloat); | |||||
return aDefault; | |||||
} | |||||
public Vector2 ReadVector2(string aXName, string aYName) | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
return new Vector2(this[aXName].AsFloat, this[aYName].AsFloat); | |||||
} | |||||
return Vector2.zero; | |||||
} | |||||
public Vector2 ReadVector2() | |||||
{ | |||||
return ReadVector2(Vector2.zero); | |||||
} | |||||
public JSONNode WriteVector2(Vector2 aVec, string aXName = "x", string aYName = "y") | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this[aXName].AsFloat = aVec.x; | |||||
this[aYName].AsFloat = aVec.y; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsFloat = aVec.x; | |||||
this[1].AsFloat = aVec.y; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Vector2 | |||||
#region Vector3 | |||||
public Vector3 ReadVector3(Vector3 aDefault) | |||||
{ | |||||
if (IsObject) | |||||
return new Vector3(this["x"].AsFloat, this["y"].AsFloat, this["z"].AsFloat); | |||||
if (IsArray) | |||||
return new Vector3(this[0].AsFloat, this[1].AsFloat, this[2].AsFloat); | |||||
return aDefault; | |||||
} | |||||
public Vector3 ReadVector3(string aXName, string aYName, string aZName) | |||||
{ | |||||
if (IsObject) | |||||
return new Vector3(this[aXName].AsFloat, this[aYName].AsFloat, this[aZName].AsFloat); | |||||
return Vector3.zero; | |||||
} | |||||
public Vector3 ReadVector3() | |||||
{ | |||||
return ReadVector3(Vector3.zero); | |||||
} | |||||
public JSONNode WriteVector3(Vector3 aVec, string aXName = "x", string aYName = "y", string aZName = "z") | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this[aXName].AsFloat = aVec.x; | |||||
this[aYName].AsFloat = aVec.y; | |||||
this[aZName].AsFloat = aVec.z; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsFloat = aVec.x; | |||||
this[1].AsFloat = aVec.y; | |||||
this[2].AsFloat = aVec.z; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Vector3 | |||||
#region Vector4 | |||||
public Vector4 ReadVector4(Vector4 aDefault) | |||||
{ | |||||
if (IsObject) | |||||
return new Vector4(this["x"].AsFloat, this["y"].AsFloat, this["z"].AsFloat, this["w"].AsFloat); | |||||
if (IsArray) | |||||
return new Vector4(this[0].AsFloat, this[1].AsFloat, this[2].AsFloat, this[3].AsFloat); | |||||
return aDefault; | |||||
} | |||||
public Vector4 ReadVector4() | |||||
{ | |||||
return ReadVector4(Vector4.zero); | |||||
} | |||||
public JSONNode WriteVector4(Vector4 aVec) | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this["x"].AsFloat = aVec.x; | |||||
this["y"].AsFloat = aVec.y; | |||||
this["z"].AsFloat = aVec.z; | |||||
this["w"].AsFloat = aVec.w; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsFloat = aVec.x; | |||||
this[1].AsFloat = aVec.y; | |||||
this[2].AsFloat = aVec.z; | |||||
this[3].AsFloat = aVec.w; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Vector4 | |||||
#region Quaternion | |||||
public Quaternion ReadQuaternion(Quaternion aDefault) | |||||
{ | |||||
if (IsObject) | |||||
return new Quaternion(this["x"].AsFloat, this["y"].AsFloat, this["z"].AsFloat, this["w"].AsFloat); | |||||
if (IsArray) | |||||
return new Quaternion(this[0].AsFloat, this[1].AsFloat, this[2].AsFloat, this[3].AsFloat); | |||||
return aDefault; | |||||
} | |||||
public Quaternion ReadQuaternion() | |||||
{ | |||||
return ReadQuaternion(Quaternion.identity); | |||||
} | |||||
public JSONNode WriteQuaternion(Quaternion aRot) | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this["x"].AsFloat = aRot.x; | |||||
this["y"].AsFloat = aRot.y; | |||||
this["z"].AsFloat = aRot.z; | |||||
this["w"].AsFloat = aRot.w; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsFloat = aRot.x; | |||||
this[1].AsFloat = aRot.y; | |||||
this[2].AsFloat = aRot.z; | |||||
this[3].AsFloat = aRot.w; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Quaternion | |||||
#region Rect | |||||
public Rect ReadRect(Rect aDefault) | |||||
{ | |||||
if (IsObject) | |||||
return new Rect(this["x"].AsFloat, this["y"].AsFloat, this["width"].AsFloat, this["height"].AsFloat); | |||||
if (IsArray) | |||||
return new Rect(this[0].AsFloat, this[1].AsFloat, this[2].AsFloat, this[3].AsFloat); | |||||
return aDefault; | |||||
} | |||||
public Rect ReadRect() | |||||
{ | |||||
return ReadRect(new Rect()); | |||||
} | |||||
public JSONNode WriteRect(Rect aRect) | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this["x"].AsFloat = aRect.x; | |||||
this["y"].AsFloat = aRect.y; | |||||
this["width"].AsFloat = aRect.width; | |||||
this["height"].AsFloat = aRect.height; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsFloat = aRect.x; | |||||
this[1].AsFloat = aRect.y; | |||||
this[2].AsFloat = aRect.width; | |||||
this[3].AsFloat = aRect.height; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Rect | |||||
#region RectOffset | |||||
public RectOffset ReadRectOffset(RectOffset aDefault) | |||||
{ | |||||
if (this is JSONObject) | |||||
return new RectOffset(this["left"].AsInt, this["right"].AsInt, this["top"].AsInt, this["bottom"].AsInt); | |||||
if (this is JSONArray) | |||||
return new RectOffset(this[0].AsInt, this[1].AsInt, this[2].AsInt, this[3].AsInt); | |||||
return aDefault; | |||||
} | |||||
public RectOffset ReadRectOffset() | |||||
{ | |||||
return ReadRectOffset(new RectOffset()); | |||||
} | |||||
public JSONNode WriteRectOffset(RectOffset aRect) | |||||
{ | |||||
if (IsObject) | |||||
{ | |||||
Inline = true; | |||||
this["left"].AsInt = aRect.left; | |||||
this["right"].AsInt = aRect.right; | |||||
this["top"].AsInt = aRect.top; | |||||
this["bottom"].AsInt = aRect.bottom; | |||||
} | |||||
else if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
this[0].AsInt = aRect.left; | |||||
this[1].AsInt = aRect.right; | |||||
this[2].AsInt = aRect.top; | |||||
this[3].AsInt = aRect.bottom; | |||||
} | |||||
return this; | |||||
} | |||||
#endregion RectOffset | |||||
#region Matrix4x4 | |||||
public Matrix4x4 ReadMatrix() | |||||
{ | |||||
Matrix4x4 result = Matrix4x4.identity; | |||||
if (IsArray) | |||||
{ | |||||
for (int i = 0; i < 16; i++) | |||||
{ | |||||
result[i] = this[i].AsFloat; | |||||
} | |||||
} | |||||
return result; | |||||
} | |||||
public JSONNode WriteMatrix(Matrix4x4 aMatrix) | |||||
{ | |||||
if (IsArray) | |||||
{ | |||||
Inline = true; | |||||
for (int i = 0; i < 16; i++) | |||||
{ | |||||
this[i].AsFloat = aMatrix[i]; | |||||
} | |||||
} | |||||
return this; | |||||
} | |||||
#endregion Matrix4x4 | |||||
} | |||||
} |
@ -0,0 +1,11 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 654270d8a6b35bb4d820487fa92bc255 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 97a61172c32476b43ba1a4b95cd2d16e | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,13 @@ | |||||
using System; | |||||
namespace SFB { | |||||
public interface IStandaloneFileBrowser { | |||||
string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect); | |||||
string[] OpenFolderPanel(string title, string directory, bool multiselect); | |||||
string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions); | |||||
void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb); | |||||
void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb); | |||||
void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb); | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 7609f7b6787a54496aa41a3053fcc76a | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: fabd0452d926f4a79b1a6ac2a3524117 | |||||
folderAsset: yes | |||||
timeCreated: 1483902786 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,145 @@ | |||||
fileFormatVersion: 2 | |||||
guid: e60958662eed5413d86143a0a69b731e | |||||
timeCreated: 1491979494 | |||||
licenseType: Pro | |||||
PluginImporter: | |||||
serializedVersion: 2 | |||||
iconMap: {} | |||||
executionOrder: {} | |||||
isPreloaded: 0 | |||||
isOverridable: 0 | |||||
platformData: | |||||
data: | |||||
first: | |||||
'': Any | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
Exclude Android: 1 | |||||
Exclude Editor: 0 | |||||
Exclude Linux: 1 | |||||
Exclude Linux64: 1 | |||||
Exclude LinuxUniversal: 1 | |||||
Exclude OSXIntel: 1 | |||||
Exclude OSXIntel64: 1 | |||||
Exclude OSXUniversal: 1 | |||||
Exclude WebGL: 1 | |||||
Exclude Win: 0 | |||||
Exclude Win64: 0 | |||||
Exclude iOS: 1 | |||||
data: | |||||
first: | |||||
'': Editor | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
OS: AnyOS | |||||
data: | |||||
first: | |||||
Android: Android | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: ARMv7 | |||||
data: | |||||
first: | |||||
Any: | |||||
second: | |||||
enabled: 0 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Editor: Editor | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
DefaultValueInitialized: true | |||||
data: | |||||
first: | |||||
Facebook: Win | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Facebook: Win64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Standalone: Linux | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: Linux64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: LinuxUniversal | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXUniversal | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: Win | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Standalone: Win64 | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Windows Store Apps: WindowsStoreApps | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
iPhone: iOS | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CompileFlags: | |||||
FrameworkDependencies: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,46 @@ | |||||
fileFormatVersion: 2 | |||||
guid: a2a9837b81577491baf2ffadec5e2852 | |||||
folderAsset: yes | |||||
timeCreated: 1491979493 | |||||
licenseType: Pro | |||||
PluginImporter: | |||||
serializedVersion: 2 | |||||
iconMap: {} | |||||
executionOrder: {} | |||||
isPreloaded: 0 | |||||
isOverridable: 0 | |||||
platformData: | |||||
data: | |||||
first: | |||||
Any: | |||||
second: | |||||
enabled: 0 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Editor: Editor | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
DefaultValueInitialized: true | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel | |||||
second: | |||||
enabled: 1 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel64 | |||||
second: | |||||
enabled: 1 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Standalone: OSXUniversal | |||||
second: | |||||
enabled: 1 | |||||
settings: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 46dc4eb12fae14a349800ec0e97ac0c2 | |||||
folderAsset: yes | |||||
timeCreated: 1505756859 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,46 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||||
<plist version="1.0"> | |||||
<dict> | |||||
<key>BuildMachineOSBuild</key> | |||||
<string>16G29</string> | |||||
<key>CFBundleDevelopmentRegion</key> | |||||
<string>English</string> | |||||
<key>CFBundleExecutable</key> | |||||
<string>StandaloneFileBrowser</string> | |||||
<key>CFBundleIdentifier</key> | |||||
<string>com.gkngkc.sfb</string> | |||||
<key>CFBundleInfoDictionaryVersion</key> | |||||
<string>6.0</string> | |||||
<key>CFBundleName</key> | |||||
<string>StandaloneFileBrowser</string> | |||||
<key>CFBundlePackageType</key> | |||||
<string>BNDL</string> | |||||
<key>CFBundleShortVersionString</key> | |||||
<string>1.0 </string> | |||||
<key>CFBundleSignature</key> | |||||
<string>????</string> | |||||
<key>CFBundleSupportedPlatforms</key> | |||||
<array> | |||||
<string>MacOSX</string> | |||||
</array> | |||||
<key>CFBundleVersion</key> | |||||
<string>1.0</string> | |||||
<key>CSResourcesFileMapped</key> | |||||
<true/> | |||||
<key>DTCompiler</key> | |||||
<string>com.apple.compilers.llvm.clang.1_0</string> | |||||
<key>DTPlatformBuild</key> | |||||
<string>9A235</string> | |||||
<key>DTPlatformVersion</key> | |||||
<string>GM</string> | |||||
<key>DTSDKBuild</key> | |||||
<string>17A360</string> | |||||
<key>DTSDKName</key> | |||||
<string>macosx10.13</string> | |||||
<key>DTXcode</key> | |||||
<string>0900</string> | |||||
<key>DTXcodeBuild</key> | |||||
<string>9A235</string> | |||||
</dict> | |||||
</plist> |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ce685769797f44046afa3e567860c94c | |||||
timeCreated: 1505756861 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ee557323b3b2e4d0f8b4d5a2fdca2f1b | |||||
folderAsset: yes | |||||
timeCreated: 1505756861 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: ddf122e0e89124ce78aacfeecb3ec554 | |||||
timeCreated: 1508179371 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,91 @@ | |||||
var StandaloneFileBrowserWebGLPlugin = { | |||||
// Open file. | |||||
// gameObjectNamePtr: GameObject name required for calling back unity side with SendMessage. And it should be unique | |||||
// filter(disabled): Filter files. Example filters: | |||||
// Match all image files: "image/*" | |||||
// Match all video files: "video/*" | |||||
// Match all audio files: "audio/*" | |||||
// Custom: ".plist,.xml,.yaml" | |||||
// multiselect(disabled): Allows multiple file selection | |||||
UploadFile: function(gameObjectNamePtr/*, filter, multiselect*/) { | |||||
gameObjectName = Pointer_stringify(gameObjectNamePtr); | |||||
// Delete if element exist | |||||
var fileInput = document.getElementById(gameObjectName) | |||||
if (fileInput) { | |||||
document.body.removeChild(fileInput); | |||||
} | |||||
fileInput = document.createElement('input'); | |||||
fileInput.setAttribute('id', gameObjectName); | |||||
fileInput.setAttribute('type', 'file'); | |||||
fileInput.setAttribute('style','display:none;'); | |||||
fileInput.setAttribute('style','visibility:hidden;'); | |||||
// if (multiselect) { | |||||
// fileInput.setAttribute('multiple', multiselect); | |||||
// } | |||||
// if (filter) { | |||||
// fileInput.setAttribute('accept', filter); | |||||
// } | |||||
fileInput.onclick = function (event) { | |||||
// File dialog opened | |||||
this.value = null; | |||||
}; | |||||
fileInput.onchange = function (event) { | |||||
// multiselect works | |||||
// for (var i = 0; i < event.target.files.length; i++) { | |||||
// console.log(URL.createObjectURL(event.target.files[i])); | |||||
// } | |||||
// File selected | |||||
SendMessage(gameObjectName, 'OnFileUploaded', URL.createObjectURL(event.target.files[0])); | |||||
// Remove after file selected | |||||
document.body.removeChild(fileInput); | |||||
} | |||||
document.body.appendChild(fileInput); | |||||
document.onmouseup = function() { | |||||
fileInput.click(); | |||||
document.onmouseup = null; | |||||
} | |||||
}, | |||||
// Open folder. - NOT IMPLEMENTED | |||||
UploadFolder: function(gameObjectNamePtr) { | |||||
gameObjectName = Pointer_stringify(gameObjectNamePtr); | |||||
SendMessage(gameObjectName, 'OnFolderUploaded', ''); | |||||
}, | |||||
// Save file | |||||
// DownloadFile method does not open SaveFileDialog like standalone builds, its just allows user to download file | |||||
// gameObjectNamePtr: GameObject name required for calling back unity side with SendMessage. And it should be unique | |||||
// DownloadFile does not return any info, just calls 'OnFileDownloaded' without any parameter | |||||
// filenamePtr: Filename with extension | |||||
// byteArray: byte[] | |||||
// byteArraySize: byte[].Length | |||||
DownloadFile: function(gameObjectNamePtr, filenamePtr, byteArray, byteArraySize) { | |||||
gameObjectName = Pointer_stringify(gameObjectNamePtr); | |||||
filename = Pointer_stringify(filenamePtr); | |||||
var bytes = new Uint8Array(byteArraySize); | |||||
for (var i = 0; i < byteArraySize; i++) { | |||||
bytes[i] = HEAPU8[byteArray + i]; | |||||
} | |||||
var downloader = window.document.createElement('a'); | |||||
downloader.setAttribute('id', gameObjectName); | |||||
downloader.href = window.URL.createObjectURL(new Blob([bytes], { type: 'application/octet-stream' })); | |||||
downloader.download = filename; | |||||
document.body.appendChild(downloader); | |||||
document.onmouseup = function() { | |||||
downloader.click(); | |||||
document.body.removeChild(downloader); | |||||
document.onmouseup = null; | |||||
SendMessage(gameObjectName, 'OnFileDownloaded'); | |||||
} | |||||
} | |||||
}; | |||||
mergeInto(LibraryManager.library, StandaloneFileBrowserWebGLPlugin); |
@ -0,0 +1,39 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 265aaf20a6d564e0fb00a9c4a7a9c300 | |||||
timeCreated: 1491979497 | |||||
licenseType: Pro | |||||
PluginImporter: | |||||
serializedVersion: 2 | |||||
iconMap: {} | |||||
executionOrder: {} | |||||
isPreloaded: 0 | |||||
isOverridable: 0 | |||||
platformData: | |||||
data: | |||||
first: | |||||
Any: | |||||
second: | |||||
enabled: 0 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Editor: Editor | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
DefaultValueInitialized: true | |||||
data: | |||||
first: | |||||
Facebook: WebGL | |||||
second: | |||||
enabled: 1 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
WebGL: WebGL | |||||
second: | |||||
enabled: 1 | |||||
settings: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,145 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 7d459a96865cc4aaab657012c6dc4833 | |||||
timeCreated: 1491979494 | |||||
licenseType: Pro | |||||
PluginImporter: | |||||
serializedVersion: 2 | |||||
iconMap: {} | |||||
executionOrder: {} | |||||
isPreloaded: 0 | |||||
isOverridable: 0 | |||||
platformData: | |||||
data: | |||||
first: | |||||
'': Any | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
Exclude Android: 1 | |||||
Exclude Editor: 0 | |||||
Exclude Linux: 1 | |||||
Exclude Linux64: 1 | |||||
Exclude LinuxUniversal: 1 | |||||
Exclude OSXIntel: 1 | |||||
Exclude OSXIntel64: 1 | |||||
Exclude OSXUniversal: 1 | |||||
Exclude WebGL: 1 | |||||
Exclude Win: 0 | |||||
Exclude Win64: 0 | |||||
Exclude iOS: 1 | |||||
data: | |||||
first: | |||||
'': Editor | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
OS: AnyOS | |||||
data: | |||||
first: | |||||
Android: Android | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: ARMv7 | |||||
data: | |||||
first: | |||||
Any: | |||||
second: | |||||
enabled: 0 | |||||
settings: {} | |||||
data: | |||||
first: | |||||
Editor: Editor | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
DefaultValueInitialized: true | |||||
data: | |||||
first: | |||||
Facebook: Win | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Facebook: Win64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Standalone: Linux | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: Linux64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: LinuxUniversal | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXIntel64 | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: OSXUniversal | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: None | |||||
data: | |||||
first: | |||||
Standalone: Win | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Standalone: Win64 | |||||
second: | |||||
enabled: 1 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
Windows Store Apps: WindowsStoreApps | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CPU: AnyCPU | |||||
data: | |||||
first: | |||||
iPhone: iOS | |||||
second: | |||||
enabled: 0 | |||||
settings: | |||||
CompileFlags: | |||||
FrameworkDependencies: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 3f5dfc38c7ff8490b8d3d8c600024d7f | |||||
folderAsset: yes | |||||
timeCreated: 1483902786 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,119 @@ | |||||
using System.Collections; | |||||
using UnityEngine; | |||||
using SFB; | |||||
public class BasicSample : MonoBehaviour { | |||||
private string _path; | |||||
void OnGUI() { | |||||
var guiScale = new Vector3(Screen.width / 800.0f, Screen.height / 600.0f, 1.0f); | |||||
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, guiScale); | |||||
GUILayout.Space(20); | |||||
GUILayout.BeginHorizontal(); | |||||
GUILayout.Space(20); | |||||
GUILayout.BeginVertical(); | |||||
// Open File Samples | |||||
if (GUILayout.Button("Open File")) { | |||||
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", false)); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open File Async")) { | |||||
StandaloneFileBrowser.OpenFilePanelAsync("Open File", "", "", false, (string[] paths) => { WriteResult(paths); }); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open File Multiple")) { | |||||
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", true)); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open File Extension")) { | |||||
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "txt", true)); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open File Directory")) { | |||||
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", Application.dataPath, "", true)); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open File Filter")) { | |||||
var extensions = new [] { | |||||
new ExtensionFilter("Image Files", "png", "jpg", "jpeg" ), | |||||
new ExtensionFilter("Sound Files", "mp3", "wav" ), | |||||
new ExtensionFilter("All Files", "*" ), | |||||
}; | |||||
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", extensions, true)); | |||||
} | |||||
GUILayout.Space(15); | |||||
// Open Folder Samples | |||||
if (GUILayout.Button("Open Folder")) { | |||||
var paths = StandaloneFileBrowser.OpenFolderPanel("Select Folder", "", true); | |||||
WriteResult(paths); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open Folder Async")) { | |||||
StandaloneFileBrowser.OpenFolderPanelAsync("Select Folder", "", true, (string[] paths) => { WriteResult(paths); }); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Open Folder Directory")) { | |||||
var paths = StandaloneFileBrowser.OpenFolderPanel("Select Folder", Application.dataPath, true); | |||||
WriteResult(paths); | |||||
} | |||||
GUILayout.Space(15); | |||||
// Save File Samples | |||||
if (GUILayout.Button("Save File")) { | |||||
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "", ""); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Save File Async")) { | |||||
StandaloneFileBrowser.SaveFilePanelAsync("Save File", "", "", "", (string path) => { WriteResult(path); }); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Save File Default Name")) { | |||||
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", ""); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Save File Default Name Ext")) { | |||||
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", "dat"); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Save File Directory")) { | |||||
_path = StandaloneFileBrowser.SaveFilePanel("Save File", Application.dataPath, "", ""); | |||||
} | |||||
GUILayout.Space(5); | |||||
if (GUILayout.Button("Save File Filter")) { | |||||
// Multiple save extension filters with more than one extension support. | |||||
var extensionList = new [] { | |||||
new ExtensionFilter("Binary", "bin"), | |||||
new ExtensionFilter("Text", "txt"), | |||||
}; | |||||
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", extensionList); | |||||
} | |||||
GUILayout.EndVertical(); | |||||
GUILayout.Space(20); | |||||
GUILayout.Label(_path); | |||||
GUILayout.EndHorizontal(); | |||||
} | |||||
public void WriteResult(string[] paths) { | |||||
if (paths.Length == 0) { | |||||
return; | |||||
} | |||||
_path = ""; | |||||
foreach (var p in paths) { | |||||
_path += p + "\n"; | |||||
} | |||||
} | |||||
public void WriteResult(string path) { | |||||
_path = path; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 5148400295519405d82bb0fa65246ea2 | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,220 @@ | |||||
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!29 &1 | |||||
OcclusionCullingSettings: | |||||
m_ObjectHideFlags: 0 | |||||
serializedVersion: 2 | |||||
m_OcclusionBakeSettings: | |||||
smallestOccluder: 5 | |||||
smallestHole: 0.25 | |||||
backfaceThreshold: 100 | |||||
m_SceneGUID: 00000000000000000000000000000000 | |||||
m_OcclusionCullingData: {fileID: 0} | |||||
--- !u!104 &2 | |||||
RenderSettings: | |||||
m_ObjectHideFlags: 0 | |||||
serializedVersion: 7 | |||||
m_Fog: 0 | |||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} | |||||
m_FogMode: 3 | |||||
m_FogDensity: 0.01 | |||||
m_LinearFogStart: 0 | |||||
m_LinearFogEnd: 300 | |||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} | |||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} | |||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} | |||||
m_AmbientIntensity: 1 | |||||
m_AmbientMode: 3 | |||||
m_SkyboxMaterial: {fileID: 0} | |||||
m_HaloStrength: 0.5 | |||||
m_FlareStrength: 1 | |||||
m_FlareFadeSpeed: 3 | |||||
m_HaloTexture: {fileID: 0} | |||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} | |||||
m_DefaultReflectionMode: 0 | |||||
m_DefaultReflectionResolution: 128 | |||||
m_ReflectionBounces: 1 | |||||
m_ReflectionIntensity: 1 | |||||
m_CustomReflection: {fileID: 0} | |||||
m_Sun: {fileID: 0} | |||||
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} | |||||
--- !u!157 &3 | |||||
LightmapSettings: | |||||
m_ObjectHideFlags: 0 | |||||
serializedVersion: 7 | |||||
m_GIWorkflowMode: 1 | |||||
m_GISettings: | |||||
serializedVersion: 2 | |||||
m_BounceScale: 1 | |||||
m_IndirectOutputScale: 1 | |||||
m_AlbedoBoost: 1 | |||||
m_TemporalCoherenceThreshold: 1 | |||||
m_EnvironmentLightingMode: 0 | |||||
m_EnableBakedLightmaps: 0 | |||||
m_EnableRealtimeLightmaps: 0 | |||||
m_LightmapEditorSettings: | |||||
serializedVersion: 4 | |||||
m_Resolution: 2 | |||||
m_BakeResolution: 40 | |||||
m_TextureWidth: 1024 | |||||
m_TextureHeight: 1024 | |||||
m_AO: 0 | |||||
m_AOMaxDistance: 1 | |||||
m_CompAOExponent: 1 | |||||
m_CompAOExponentDirect: 0 | |||||
m_Padding: 2 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_LightmapsBakeMode: 1 | |||||
m_TextureCompression: 1 | |||||
m_DirectLightInLightProbes: 1 | |||||
m_FinalGather: 0 | |||||
m_FinalGatherFiltering: 1 | |||||
m_FinalGatherRayCount: 256 | |||||
m_ReflectionCompression: 2 | |||||
m_LightingDataAsset: {fileID: 0} | |||||
m_RuntimeCPUUsage: 25 | |||||
--- !u!196 &4 | |||||
NavMeshSettings: | |||||
serializedVersion: 2 | |||||
m_ObjectHideFlags: 0 | |||||
m_BuildSettings: | |||||
serializedVersion: 2 | |||||
agentTypeID: 0 | |||||
agentRadius: 0.5 | |||||
agentHeight: 2 | |||||
agentSlope: 45 | |||||
agentClimb: 0.4 | |||||
ledgeDropHeight: 0 | |||||
maxJumpAcrossDistance: 0 | |||||
minRegionArea: 2 | |||||
manualCellSize: 0 | |||||
cellSize: 0.16666667 | |||||
accuratePlacement: 0 | |||||
m_NavMeshData: {fileID: 0} | |||||
--- !u!1 &382763637 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 382763642} | |||||
- component: {fileID: 382763641} | |||||
- component: {fileID: 382763640} | |||||
- component: {fileID: 382763639} | |||||
- component: {fileID: 382763638} | |||||
m_Layer: 0 | |||||
m_Name: Main Camera | |||||
m_TagString: MainCamera | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!81 &382763638 | |||||
AudioListener: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 382763637} | |||||
m_Enabled: 1 | |||||
--- !u!124 &382763639 | |||||
Behaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 382763637} | |||||
m_Enabled: 1 | |||||
--- !u!92 &382763640 | |||||
Behaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 382763637} | |||||
m_Enabled: 1 | |||||
--- !u!20 &382763641 | |||||
Camera: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 382763637} | |||||
m_Enabled: 1 | |||||
serializedVersion: 2 | |||||
m_ClearFlags: 1 | |||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} | |||||
m_NormalizedViewPortRect: | |||||
serializedVersion: 2 | |||||
x: 0 | |||||
y: 0 | |||||
width: 1 | |||||
height: 1 | |||||
near clip plane: 0.3 | |||||
far clip plane: 1000 | |||||
field of view: 60 | |||||
orthographic: 1 | |||||
orthographic size: 5 | |||||
m_Depth: -1 | |||||
m_CullingMask: | |||||
serializedVersion: 2 | |||||
m_Bits: 4294967295 | |||||
m_RenderingPath: -1 | |||||
m_TargetTexture: {fileID: 0} | |||||
m_TargetDisplay: 0 | |||||
m_TargetEye: 3 | |||||
m_HDR: 0 | |||||
m_OcclusionCulling: 1 | |||||
m_StereoConvergence: 10 | |||||
m_StereoSeparation: 0.022 | |||||
m_StereoMirrorMode: 0 | |||||
--- !u!4 &382763642 | |||||
Transform: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 382763637} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 0, z: -10} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 0} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!1 &986049433 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 986049435} | |||||
- component: {fileID: 986049434} | |||||
m_Layer: 0 | |||||
m_Name: GameObject | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!114 &986049434 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 986049433} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 5148400295519405d82bb0fa65246ea2, type: 3} | |||||
m_Name: | |||||
m_EditorClassIdentifier: | |||||
--- !u!4 &986049435 | |||||
Transform: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 986049433} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 0, z: 0} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 0} | |||||
m_RootOrder: 1 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: d97280fe82b874466870f709c3315d41 | |||||
timeCreated: 1483902786 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,60 @@ | |||||
using System.Text; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using System.Runtime.InteropServices; | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
using UnityEngine.EventSystems; | |||||
using SFB; | |||||
[RequireComponent(typeof(Button))] | |||||
public class CanvasSampleOpenFileImage : MonoBehaviour, IPointerDownHandler { | |||||
public string Title = ""; | |||||
public string FileName = ""; | |||||
public string Directory = ""; | |||||
public string Extension = ""; | |||||
public bool Multiselect = false; | |||||
public RawImage output; | |||||
#if UNITY_WEBGL && !UNITY_EDITOR | |||||
// | |||||
// WebGL | |||||
// | |||||
[DllImport("__Internal")] | |||||
private static extern void UploadFile(string id); | |||||
public void OnPointerDown(PointerEventData eventData) { | |||||
UploadFile(gameObject.name); | |||||
} | |||||
// Called from browser | |||||
public void OnFileUploaded(string url) { | |||||
StartCoroutine(OutputRoutine(url)); | |||||
} | |||||
#else | |||||
// | |||||
// Standalone platforms & editor | |||||
// | |||||
public void OnPointerDown(PointerEventData eventData) { } | |||||
void Start() { | |||||
var button = GetComponent<Button>(); | |||||
button.onClick.AddListener(OnClick); | |||||
} | |||||
private void OnClick() { | |||||
var paths = StandaloneFileBrowser.OpenFilePanel(Title, Directory, Extension, Multiselect); | |||||
if (paths.Length > 0) { | |||||
StartCoroutine(OutputRoutine(new System.Uri(paths[0]).AbsoluteUri)); | |||||
} | |||||
} | |||||
#endif | |||||
private IEnumerator OutputRoutine(string url) { | |||||
Debug.Log("URL: " + url); | |||||
var loader = new WWW(url); | |||||
yield return loader; | |||||
output.texture = loader.texture; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 331c95b7bf39e4792acecff50a972040 | |||||
timeCreated: 1489946149 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,59 @@ | |||||
using System.Text; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using System.Runtime.InteropServices; | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
using UnityEngine.EventSystems; | |||||
using SFB; | |||||
[RequireComponent(typeof(Button))] | |||||
public class CanvasSampleOpenFileText : MonoBehaviour, IPointerDownHandler { | |||||
public string Title = ""; | |||||
public string FileName = ""; | |||||
public string Directory = ""; | |||||
public string Extension = ""; | |||||
public bool Multiselect = false; | |||||
public Text output; | |||||
#if UNITY_WEBGL && !UNITY_EDITOR | |||||
// | |||||
// WebGL | |||||
// | |||||
[DllImport("__Internal")] | |||||
private static extern void UploadFile(string id); | |||||
public void OnPointerDown(PointerEventData eventData) { | |||||
UploadFile(gameObject.name); | |||||
} | |||||
// Called from browser | |||||
public void OnFileUploaded(string url) { | |||||
StartCoroutine(OutputRoutine(url)); | |||||
} | |||||
#else | |||||
// | |||||
// Standalone platforms & editor | |||||
// | |||||
public void OnPointerDown(PointerEventData eventData) { } | |||||
void Start() { | |||||
var button = GetComponent<Button>(); | |||||
button.onClick.AddListener(OnClick); | |||||
} | |||||
private void OnClick() { | |||||
var paths = StandaloneFileBrowser.OpenFilePanel(Title, Directory, Extension, Multiselect); | |||||
if (paths.Length > 0) { | |||||
StartCoroutine(OutputRoutine(new System.Uri(paths[0]).AbsoluteUri)); | |||||
} | |||||
} | |||||
#endif | |||||
private IEnumerator OutputRoutine(string url) { | |||||
var loader = new WWW(url); | |||||
yield return loader; | |||||
output.text = loader.text; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 99a65d6437df64949b37cba4eadc67a2 | |||||
timeCreated: 1489946149 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,68 @@ | |||||
using System.IO; | |||||
using System.Text; | |||||
using System.Runtime.InteropServices; | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
using UnityEngine.EventSystems; | |||||
using SFB; | |||||
[RequireComponent(typeof(Button))] | |||||
public class CanvasSampleSaveFileImage : MonoBehaviour, IPointerDownHandler { | |||||
public string Title = ""; | |||||
public string Directory = ""; | |||||
public string FileName = ""; | |||||
public string Extension = ""; | |||||
private byte[] _textureBytes; | |||||
void Awake() { | |||||
// Create red texture | |||||
var width = 100; | |||||
var height = 100; | |||||
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false); | |||||
for (int i = 0; i < width; i++) { | |||||
for (int j = 0; j < height; j++) { | |||||
tex.SetPixel(i, j, Color.red); | |||||
} | |||||
} | |||||
tex.Apply(); | |||||
_textureBytes = tex.EncodeToPNG(); | |||||
UnityEngine.Object.Destroy(tex); | |||||
} | |||||
#if UNITY_WEBGL && !UNITY_EDITOR | |||||
// | |||||
// WebGL | |||||
// | |||||
[DllImport("__Internal")] | |||||
private static extern void DownloadFile(string id, string filename, byte[] byteArray, int byteArraySize); | |||||
// Broser plugin should be called in OnPointerDown. | |||||
public void OnPointerDown(PointerEventData eventData) { | |||||
DownloadFile(gameObject.name, FileName + "." + Extension, _textureBytes, _textureBytes.Length); | |||||
} | |||||
// Called from browser | |||||
public void OnFileDownloaded() { | |||||
// | |||||
} | |||||
#else | |||||
// | |||||
// Standalone platforms & editor | |||||
// | |||||
public void OnPointerDown(PointerEventData eventData) { } | |||||
// Listen OnClick event in standlone builds | |||||
void Start() { | |||||
var button = GetComponent<Button>(); | |||||
button.onClick.AddListener(OnClick); | |||||
} | |||||
public void OnClick() { | |||||
var path = StandaloneFileBrowser.SaveFilePanel(Title, Directory, FileName, Extension); | |||||
if (!string.IsNullOrEmpty(path)) { | |||||
File.WriteAllBytes(path, _textureBytes); | |||||
} | |||||
} | |||||
#endif | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 6e681018aa67241a69b8447678ec3b4e | |||||
timeCreated: 1489946149 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,55 @@ | |||||
using System.IO; | |||||
using System.Text; | |||||
using System.Runtime.InteropServices; | |||||
using UnityEngine; | |||||
using UnityEngine.UI; | |||||
using UnityEngine.EventSystems; | |||||
using SFB; | |||||
[RequireComponent(typeof(Button))] | |||||
public class CanvasSampleSaveFileText : MonoBehaviour, IPointerDownHandler { | |||||
public string Title = ""; | |||||
public string Directory = ""; | |||||
public string FileName = ""; | |||||
public string Extension = ""; | |||||
// Sample text data | |||||
private string _data = "Example text created by StandaloneFileBrowser"; | |||||
#if UNITY_WEBGL && !UNITY_EDITOR | |||||
// | |||||
// WebGL | |||||
// | |||||
[DllImport("__Internal")] | |||||
private static extern void DownloadFile(string id, string filename, byte[] byteArray, int byteArraySize); | |||||
// Broser plugin should be called in OnPointerDown. | |||||
public void OnPointerDown(PointerEventData eventData) { | |||||
var bytes = Encoding.UTF8.GetBytes(_data); | |||||
DownloadFile(gameObject.name, FileName + "." + Extension, bytes, bytes.Length); | |||||
} | |||||
// Called from browser | |||||
public void OnFileDownloaded() { | |||||
// | |||||
} | |||||
#else | |||||
// | |||||
// Standalone platforms & editor | |||||
// | |||||
public void OnPointerDown(PointerEventData eventData) { } | |||||
// Listen OnClick event in standlone builds | |||||
void Start() { | |||||
var button = GetComponent<Button>(); | |||||
button.onClick.AddListener(OnClick); | |||||
} | |||||
public void OnClick() { | |||||
var path = StandaloneFileBrowser.SaveFilePanel(Title, Directory, FileName, Extension); | |||||
if (!string.IsNullOrEmpty(path)) { | |||||
File.WriteAllText(path, _data); | |||||
} | |||||
} | |||||
#endif | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 8e97f52f0bd664ee78305dae0094a755 | |||||
timeCreated: 1489946149 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||||
fileFormatVersion: 2 | |||||
guid: c0e4eec5741834194a946535d535405c | |||||
timeCreated: 1483902786 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,151 @@ | |||||
using System; | |||||
namespace SFB { | |||||
public struct ExtensionFilter { | |||||
public string Name; | |||||
public string[] Extensions; | |||||
public ExtensionFilter(string filterName, params string[] filterExtensions) { | |||||
Name = filterName; | |||||
Extensions = filterExtensions; | |||||
} | |||||
} | |||||
public class StandaloneFileBrowser { | |||||
private static IStandaloneFileBrowser _platformWrapper = null; | |||||
static StandaloneFileBrowser() { | |||||
#if UNITY_STANDALONE_OSX | |||||
_platformWrapper = new StandaloneFileBrowserMac(); | |||||
#elif UNITY_STANDALONE_WIN | |||||
_platformWrapper = new StandaloneFileBrowserWindows(); | |||||
#elif UNITY_EDITOR | |||||
_platformWrapper = new StandaloneFileBrowserEditor(); | |||||
#endif | |||||
} | |||||
/// <summary> | |||||
/// Native open file dialog | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="extension">Allowed extension</param> | |||||
/// <param name="multiselect">Allow multiple file selection</param> | |||||
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns> | |||||
public static string[] OpenFilePanel(string title, string directory, string extension, bool multiselect) { | |||||
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) }; | |||||
return OpenFilePanel(title, directory, extensions, multiselect); | |||||
} | |||||
/// <summary> | |||||
/// Native open file dialog | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param> | |||||
/// <param name="multiselect">Allow multiple file selection</param> | |||||
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns> | |||||
public static string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) { | |||||
return _platformWrapper.OpenFilePanel(title, directory, extensions, multiselect); | |||||
} | |||||
/// <summary> | |||||
/// Native open file dialog async | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="extension">Allowed extension</param> | |||||
/// <param name="multiselect">Allow multiple file selection</param> | |||||
/// <param name="cb">Callback")</param> | |||||
public static void OpenFilePanelAsync(string title, string directory, string extension, bool multiselect, Action<string[]> cb) { | |||||
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) }; | |||||
OpenFilePanelAsync(title, directory, extensions, multiselect, cb); | |||||
} | |||||
/// <summary> | |||||
/// Native open file dialog async | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param> | |||||
/// <param name="multiselect">Allow multiple file selection</param> | |||||
/// <param name="cb">Callback")</param> | |||||
public static void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) { | |||||
_platformWrapper.OpenFilePanelAsync(title, directory, extensions, multiselect, cb); | |||||
} | |||||
/// <summary> | |||||
/// Native open folder dialog | |||||
/// NOTE: Multiple folder selection doesn't supported on Windows | |||||
/// </summary> | |||||
/// <param name="title"></param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="multiselect"></param> | |||||
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns> | |||||
public static string[] OpenFolderPanel(string title, string directory, bool multiselect) { | |||||
return _platformWrapper.OpenFolderPanel(title, directory, multiselect); | |||||
} | |||||
/// <summary> | |||||
/// Native open folder dialog async | |||||
/// NOTE: Multiple folder selection doesn't supported on Windows | |||||
/// </summary> | |||||
/// <param name="title"></param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="multiselect"></param> | |||||
/// <param name="cb">Callback")</param> | |||||
public static void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) { | |||||
_platformWrapper.OpenFolderPanelAsync(title, directory, multiselect, cb); | |||||
} | |||||
/// <summary> | |||||
/// Native save file dialog | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="defaultName">Default file name</param> | |||||
/// <param name="extension">File extension</param> | |||||
/// <returns>Returns chosen path. Empty string when cancelled</returns> | |||||
public static string SaveFilePanel(string title, string directory, string defaultName , string extension) { | |||||
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) }; | |||||
return SaveFilePanel(title, directory, defaultName, extensions); | |||||
} | |||||
/// <summary> | |||||
/// Native save file dialog | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="defaultName">Default file name</param> | |||||
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param> | |||||
/// <returns>Returns chosen path. Empty string when cancelled</returns> | |||||
public static string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) { | |||||
return _platformWrapper.SaveFilePanel(title, directory, defaultName, extensions); | |||||
} | |||||
/// <summary> | |||||
/// Native save file dialog async | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="defaultName">Default file name</param> | |||||
/// <param name="extension">File extension</param> | |||||
/// <param name="cb">Callback")</param> | |||||
public static void SaveFilePanelAsync(string title, string directory, string defaultName , string extension, Action<string> cb) { | |||||
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) }; | |||||
SaveFilePanelAsync(title, directory, defaultName, extensions, cb); | |||||
} | |||||
/// <summary> | |||||
/// Native save file dialog async | |||||
/// </summary> | |||||
/// <param name="title">Dialog title</param> | |||||
/// <param name="directory">Root directory</param> | |||||
/// <param name="defaultName">Default file name</param> | |||||
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param> | |||||
/// <param name="cb">Callback")</param> | |||||
public static void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) { | |||||
_platformWrapper.SaveFilePanelAsync(title, directory, defaultName, extensions, cb); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 3c708be74128e4ced9b79eaaf80e8443 | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,56 @@ | |||||
#if UNITY_EDITOR | |||||
using System; | |||||
using UnityEditor; | |||||
namespace SFB { | |||||
public class StandaloneFileBrowserEditor : IStandaloneFileBrowser { | |||||
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) { | |||||
string path = ""; | |||||
if (extensions == null) { | |||||
path = EditorUtility.OpenFilePanel(title, directory, ""); | |||||
} | |||||
else { | |||||
path = EditorUtility.OpenFilePanelWithFilters(title, directory, GetFilterFromFileExtensionList(extensions)); | |||||
} | |||||
return string.IsNullOrEmpty(path) ? new string[0] : new[] { path }; | |||||
} | |||||
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) { | |||||
cb.Invoke(OpenFilePanel(title, directory, extensions, multiselect)); | |||||
} | |||||
public string[] OpenFolderPanel(string title, string directory, bool multiselect) { | |||||
var path = EditorUtility.OpenFolderPanel(title, directory, ""); | |||||
return string.IsNullOrEmpty(path) ? new string[0] : new[] {path}; | |||||
} | |||||
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) { | |||||
cb.Invoke(OpenFolderPanel(title, directory, multiselect)); | |||||
} | |||||
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) { | |||||
var ext = extensions != null ? extensions[0].Extensions[0] : ""; | |||||
var name = string.IsNullOrEmpty(ext) ? defaultName : defaultName + "." + ext; | |||||
return EditorUtility.SaveFilePanel(title, directory, name, ext); | |||||
} | |||||
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) { | |||||
cb.Invoke(SaveFilePanel(title, directory, defaultName, extensions)); | |||||
} | |||||
// EditorUtility.OpenFilePanelWithFilters extension filter format | |||||
private static string[] GetFilterFromFileExtensionList(ExtensionFilter[] extensions) { | |||||
var filters = new string[extensions.Length * 2]; | |||||
for (int i = 0; i < extensions.Length; i++) { | |||||
filters[(i * 2)] = extensions[i].Name; | |||||
filters[(i * 2) + 1] = string.Join(",", extensions[i].Extensions); | |||||
} | |||||
return filters; | |||||
} | |||||
} | |||||
} | |||||
#endif |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 2650af8de2cda46b99b1bc7cf5d30ca5 | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,104 @@ | |||||
#if UNITY_STANDALONE_OSX | |||||
using System; | |||||
using System.Runtime.InteropServices; | |||||
namespace SFB { | |||||
public class StandaloneFileBrowserMac : IStandaloneFileBrowser { | |||||
private static Action<string[]> _openFileCb; | |||||
private static Action<string[]> _openFolderCb; | |||||
private static Action<string> _saveFileCb; | |||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)] | |||||
public delegate void AsyncCallback(string path); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern IntPtr DialogOpenFilePanel(string title, string directory, string extension, bool multiselect); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern void DialogOpenFilePanelAsync(string title, string directory, string extension, bool multiselect, AsyncCallback callback); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern IntPtr DialogOpenFolderPanel(string title, string directory, bool multiselect); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern void DialogOpenFolderPanelAsync(string title, string directory, bool multiselect, AsyncCallback callback); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern IntPtr DialogSaveFilePanel(string title, string directory, string defaultName, string extension); | |||||
[DllImport("StandaloneFileBrowser")] | |||||
private static extern void DialogSaveFilePanelAsync(string title, string directory, string defaultName, string extension, AsyncCallback callback); | |||||
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) { | |||||
var paths = Marshal.PtrToStringAnsi(DialogOpenFilePanel( | |||||
title, | |||||
directory, | |||||
GetFilterFromFileExtensionList(extensions), | |||||
multiselect)); | |||||
return paths.Split((char)28); | |||||
} | |||||
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) { | |||||
_openFileCb = cb; | |||||
DialogOpenFilePanelAsync( | |||||
title, | |||||
directory, | |||||
GetFilterFromFileExtensionList(extensions), | |||||
multiselect, | |||||
(string result) => { _openFileCb.Invoke(result.Split((char)28)); }); | |||||
} | |||||
public string[] OpenFolderPanel(string title, string directory, bool multiselect) { | |||||
var paths = Marshal.PtrToStringAnsi(DialogOpenFolderPanel( | |||||
title, | |||||
directory, | |||||
multiselect)); | |||||
return paths.Split((char)28); | |||||
} | |||||
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) { | |||||
_openFolderCb = cb; | |||||
DialogOpenFolderPanelAsync( | |||||
title, | |||||
directory, | |||||
multiselect, | |||||
(string result) => { _openFolderCb.Invoke(result.Split((char)28)); }); | |||||
} | |||||
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) { | |||||
return Marshal.PtrToStringAnsi(DialogSaveFilePanel( | |||||
title, | |||||
directory, | |||||
defaultName, | |||||
GetFilterFromFileExtensionList(extensions))); | |||||
} | |||||
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) { | |||||
_saveFileCb = cb; | |||||
DialogSaveFilePanelAsync( | |||||
title, | |||||
directory, | |||||
defaultName, | |||||
GetFilterFromFileExtensionList(extensions), | |||||
(string result) => { _saveFileCb.Invoke(result); }); | |||||
} | |||||
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) { | |||||
if (extensions == null) { | |||||
return ""; | |||||
} | |||||
var filterString = ""; | |||||
foreach (var filter in extensions) { | |||||
filterString += filter.Name + ";"; | |||||
foreach (var ext in filter.Extensions) { | |||||
filterString += ext + ","; | |||||
} | |||||
filterString = filterString.Remove(filterString.Length - 1); | |||||
filterString += "|"; | |||||
} | |||||
filterString = filterString.Remove(filterString.Length - 1); | |||||
return filterString; | |||||
} | |||||
} | |||||
} | |||||
#endif |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: bcb49ddb0ed5644fda9c3b055cafa27a | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -0,0 +1,134 @@ | |||||
#if UNITY_STANDALONE_WIN | |||||
using System; | |||||
using System.IO; | |||||
using System.Windows.Forms; | |||||
using System.Runtime.InteropServices; | |||||
using Ookii.Dialogs; | |||||
namespace SFB { | |||||
// For fullscreen support | |||||
// - WindowWrapper class and GetActiveWindow() are required for modal file dialog. | |||||
// - "PlayerSettings/Visible In Background" should be enabled, otherwise when file dialog opened app window minimizes automatically. | |||||
public class WindowWrapper : IWin32Window { | |||||
private IntPtr _hwnd; | |||||
public WindowWrapper(IntPtr handle) { _hwnd = handle; } | |||||
public IntPtr Handle { get { return _hwnd; } } | |||||
} | |||||
public class StandaloneFileBrowserWindows : IStandaloneFileBrowser { | |||||
[DllImport("user32.dll")] | |||||
private static extern IntPtr GetActiveWindow(); | |||||
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) { | |||||
var fd = new VistaOpenFileDialog(); | |||||
fd.Title = title; | |||||
if (extensions != null) { | |||||
fd.Filter = GetFilterFromFileExtensionList(extensions); | |||||
fd.FilterIndex = 1; | |||||
} | |||||
else { | |||||
fd.Filter = string.Empty; | |||||
} | |||||
fd.Multiselect = multiselect; | |||||
if (!string.IsNullOrEmpty(directory)) { | |||||
fd.FileName = GetDirectoryPath(directory); | |||||
} | |||||
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow())); | |||||
var filenames = res == DialogResult.OK ? fd.FileNames : new string[0]; | |||||
fd.Dispose(); | |||||
return filenames; | |||||
} | |||||
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) { | |||||
cb.Invoke(OpenFilePanel(title, directory, extensions, multiselect)); | |||||
} | |||||
public string[] OpenFolderPanel(string title, string directory, bool multiselect) { | |||||
var fd = new VistaFolderBrowserDialog(); | |||||
fd.Description = title; | |||||
if (!string.IsNullOrEmpty(directory)) { | |||||
fd.SelectedPath = GetDirectoryPath(directory); | |||||
} | |||||
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow())); | |||||
var filenames = res == DialogResult.OK ? new []{ fd.SelectedPath } : new string[0]; | |||||
fd.Dispose(); | |||||
return filenames; | |||||
} | |||||
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) { | |||||
cb.Invoke(OpenFolderPanel(title, directory, multiselect)); | |||||
} | |||||
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) { | |||||
var fd = new VistaSaveFileDialog(); | |||||
fd.Title = title; | |||||
var finalFilename = ""; | |||||
if (!string.IsNullOrEmpty(directory)) { | |||||
finalFilename = GetDirectoryPath(directory); | |||||
} | |||||
if (!string.IsNullOrEmpty(defaultName)) { | |||||
finalFilename += defaultName; | |||||
} | |||||
fd.FileName = finalFilename; | |||||
if (extensions != null) { | |||||
fd.Filter = GetFilterFromFileExtensionList(extensions); | |||||
fd.FilterIndex = 1; | |||||
fd.DefaultExt = extensions[0].Extensions[0]; | |||||
fd.AddExtension = true; | |||||
} | |||||
else { | |||||
fd.DefaultExt = string.Empty; | |||||
fd.Filter = string.Empty; | |||||
fd.AddExtension = false; | |||||
} | |||||
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow())); | |||||
var filename = res == DialogResult.OK ? fd.FileName : ""; | |||||
fd.Dispose(); | |||||
return filename; | |||||
} | |||||
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) { | |||||
cb.Invoke(SaveFilePanel(title, directory, defaultName, extensions)); | |||||
} | |||||
// .NET Framework FileDialog Filter format | |||||
// https://msdn.microsoft.com/en-us/library/microsoft.win32.filedialog.filter | |||||
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) { | |||||
var filterString = ""; | |||||
foreach (var filter in extensions) { | |||||
filterString += filter.Name + "("; | |||||
foreach (var ext in filter.Extensions) { | |||||
filterString += "*." + ext + ","; | |||||
} | |||||
filterString = filterString.Remove(filterString.Length - 1); | |||||
filterString += ") |"; | |||||
foreach (var ext in filter.Extensions) { | |||||
filterString += "*." + ext + "; "; | |||||
} | |||||
filterString += "|"; | |||||
} | |||||
filterString = filterString.Remove(filterString.Length - 1); | |||||
return filterString; | |||||
} | |||||
private static string GetDirectoryPath(string directory) { | |||||
var directoryPath = Path.GetFullPath(directory); | |||||
if (!directoryPath.EndsWith("\\")) { | |||||
directoryPath += "\\"; | |||||
} | |||||
return Path.GetDirectoryName(directoryPath) + Path.DirectorySeparatorChar; | |||||
} | |||||
} | |||||
} | |||||
#endif |
@ -0,0 +1,12 @@ | |||||
fileFormatVersion: 2 | |||||
guid: 194e247414a78461d83ae606c1b96917 | |||||
timeCreated: 1483902788 | |||||
licenseType: Pro | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
@ -1 +1 @@ | |||||
m_EditorVersion: 2018.1.0f2 | |||||
m_EditorVersion: 2018.2.12f1 |