Last active
February 23, 2016 08:40
-
-
Save fuqunaga/3c7adee2e7b732c82512 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
public static class GUIUtil | |
{ | |
public class Folds : Dictionary<string, Fold> | |
{ | |
public void Add(string name, Action action, bool enableFirst = false) | |
{ | |
Fold fold; | |
if (TryGetValue(name, out fold)) | |
{ | |
fold.Add(action); | |
} | |
else { | |
Add(name, new Fold(name, action, enableFirst)); | |
} | |
} | |
public void OnGUI() | |
{ | |
Values.ToList().ForEach(f => f.OnGUI()); | |
} | |
} | |
public class Fold | |
{ | |
bool enable; | |
string name; | |
Action draw; | |
public Fold(string n, Action action, bool enableFirst = false) | |
{ | |
name = n; | |
draw += action; | |
enable = enableFirst; | |
} | |
public void Add(Action action) | |
{ | |
draw += action; | |
} | |
public void OnGUI() | |
{ | |
enable = GUILayout.Toggle(enable, name); | |
if (enable) | |
{ | |
using (var v = new GUILayout.VerticalScope("window")) | |
{ | |
draw(); | |
} | |
} | |
} | |
} | |
public static T Field<T>(T v, string label = "") | |
{ | |
var type = typeof(T); | |
Func<T> func = (Func<T>)(() => (T)Convert.ChangeType(GUILayout.TextField(v.ToString()), type)); | |
if (type == typeof(bool)) func = (Func<T>)(() => (T)Convert.ChangeType(GUILayout.Toggle(Convert.ToBoolean(v), ""), type)); | |
if (type == typeof(Vector2)) | |
{ | |
func = (Func<T>)(() => | |
{ | |
var vVec2 = (Vector2)Convert.ChangeType(v, type); | |
vVec2.x = Field(vVec2.x); | |
vVec2.y = Field(vVec2.y); | |
return (T)Convert.ChangeType(vVec2, type); | |
}); | |
} | |
else if (type.IsEnum) func = (Func<T>)(() => | |
{ | |
var enumValues = Enum.GetValues(type).OfType<T>().ToList(); | |
var isFlag = type.GetCustomAttributes(typeof(System.FlagsAttribute), true).Any(); | |
if (isFlag) | |
{ | |
var flagV = Convert.ToUInt64(v); | |
enumValues.ForEach(value => | |
{ | |
var flag = Convert.ToUInt64(value); | |
if (flag > 0) | |
{ | |
var has = (flag & flagV) == flag; | |
has = GUILayout.Toggle(has, value.ToString()); | |
flagV = has ? (flagV | flag) : (flagV & ~flag); | |
} | |
}); | |
v = (T)Enum.ToObject(type, flagV); | |
} | |
else | |
{ | |
var valueNames = enumValues.Select(value => value.ToString()).ToArray(); | |
var idx = enumValues.IndexOf(v); | |
idx = GUILayout.SelectionGrid( | |
idx, | |
valueNames, | |
valueNames.Length); | |
v = enumValues.ElementAtOrDefault(idx); | |
} | |
return v; | |
}); | |
T ret = default(T); | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
if (!string.IsNullOrEmpty(label)) GUILayout.Label(label); | |
ret = func(); | |
} | |
return ret; | |
} | |
public static int IntButton(int v, string label = "") | |
{ | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
v = Field(v, label); | |
if (GUILayout.Button("+")) v++; | |
if (GUILayout.Button("-")) v--; | |
} | |
return v; | |
} | |
public static int Slider(int v, int min, int max, string label = "") | |
{ | |
return Mathf.FloorToInt(Slider((float)v, min, max, label)); | |
} | |
public static float Slider(float v, string label = "") { return Slider(v, 0f, 1f, label); } | |
public static float Slider(float v, float min, float max, string label = "") | |
{ | |
float ret = default(float); | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
if (!string.IsNullOrEmpty(label)) GUILayout.Label(label); | |
ret = GUILayout.HorizontalSlider(v, min, max, GUILayout.MinWidth(200)); | |
ret = Field(ret); | |
} | |
return ret; | |
} | |
public static Vector2 Vector2(Vector2 v, string label = "") | |
{ | |
if (!string.IsNullOrEmpty(label)) GUILayout.Label(label); | |
return new Vector2(Field(v.x), Field(v.y)); | |
} | |
public static void TexWindow(List<RenderTexture> texs, string label) | |
{ | |
var offset = 20; | |
var x = offset; | |
var y = offset; | |
var hMax = 0; | |
GUI.Box(new Rect(0, 0, Screen.width, Screen.height), label, "Window"); | |
texs.ForEach(tex => | |
{ | |
var w = tex.width; | |
var h = tex.height; | |
hMax = Mathf.Max(hMax, h); | |
if (x + w >= Screen.width - offset) | |
{ | |
x = 0; | |
y += hMax + offset; | |
hMax = h; | |
} | |
GUI.DrawTexture(new Rect(x, y, w, h), tex, ScaleMode.ScaleToFit, false); | |
x += w + offset; | |
}); | |
} | |
} | |
[Serializable] | |
public class PrefsString : PrefsParam<string> | |
{ | |
public PrefsString(string key, string defaultValue = default(string)) : base(key, defaultValue) { } | |
} | |
[Serializable] | |
public class PrefsInt : PrefsParam<int> | |
{ | |
public PrefsInt(string key, int defaultValue = default(int)) : base(key, defaultValue) { } | |
} | |
[Serializable] | |
public class PrefsFloat : PrefsParam<float> | |
{ | |
public PrefsFloat(string key, float defaultValue = default(float)) : base(key, defaultValue) { } | |
public void OnGUISlider(string label = null) { OnGUISlider(0f, 1f, label); } | |
public void OnGUISlider(float min, float max, string label = null) | |
{ | |
OnGUIwithButton(() => | |
{ | |
var v = Get(); | |
GUILayout.Label(label ?? key); | |
v = GUIUtil.Slider(v, min, max); | |
GUILayout.FlexibleSpace(); | |
Set(v); | |
}); | |
} | |
} | |
[Serializable] | |
public class PrefsBool : PrefsParam<bool> | |
{ | |
public PrefsBool(string key, bool defaultValue = default(bool)) : base(key, defaultValue) { } | |
} | |
[Serializable] | |
public class PrefsVector2 : _PrefsParam<Vector2> | |
{ | |
public PrefsVector2(string key, Vector2 defaultValue = default(Vector2)) : base(key, defaultValue) { } | |
public override Vector2 Get() | |
{ | |
return PlayerPrefsVector2.Get(key, defaultValue); | |
} | |
public override void Set(Vector2 v) | |
{ | |
PlayerPrefsVector2.Set(key, v); | |
} | |
public override void Delete() { PlayerPrefsVector2.DeleteKey(key); } | |
protected override void _OnGUI(string key, string label, Vector2 defaultValue) | |
{ | |
PlayerPrefsVector2.OnGUI(key, label, defaultValue); | |
} | |
public void OnGUISlider(string label = null) { OnGUISlider(Vector2.zero, Vector2.one, label); } | |
public void OnGUISlider(Vector2 min, Vector2 max, string label = null) | |
{ | |
OnGUIwithButton(() => PlayerPrefsVector2.OnGUISlider(key, label, defaultValue, min, max)); | |
} | |
} | |
public class PrefsParam<T> : _PrefsParam<T> | |
{ | |
public PrefsParam(string key, T defaultValue = default(T)) : base(key, defaultValue) { } | |
public override T Get() { return PlayerPrefs<T>.Get(key, defaultValue); } | |
public override void Set(T v) { PlayerPrefs<T>.Set(key, v); } | |
public override void Delete() { PlayerPrefs.DeleteKey(key); } | |
protected override void _OnGUI(string key, string label = null, T defaultValue = default(T)) | |
{ | |
PlayerPrefs<T>.OnGUI(key, label, defaultValue); | |
} | |
} | |
public abstract class _PrefsParam<T> | |
{ | |
public string key; | |
[SerializeField] | |
protected T defaultValue; | |
public _PrefsParam(string key, T defaultValue = default(T)) | |
{ | |
this.key = key; | |
this.defaultValue = defaultValue; | |
} | |
public static implicit operator T(_PrefsParam<T> me) | |
{ | |
return me.Get(); | |
} | |
public abstract T Get(); | |
public abstract void Set(T v); | |
public void SetWithDefault(T v) { Set(v); defaultValue = v; } | |
public abstract void Delete(); | |
protected abstract void _OnGUI(string key, string label = null, T defaultValue = default(T)); | |
public void OnGUI(string label = null) | |
{ | |
OnGUIwithButton(() => _OnGUI(key, label, defaultValue)); | |
} | |
protected void OnGUIwithButton(System.Action onGUIFunc) | |
{ | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
onGUIFunc(); | |
if (GUILayout.Button("default", GUILayout.Width(60f))) | |
{ | |
Set(defaultValue); | |
} | |
} | |
} | |
} | |
public static class PlayerPrefsVector2 | |
{ | |
const string POSTFIX_X = "x"; | |
const string POSTFIX_Y = "y"; | |
public static void OnGUISlider(string key, string label, Vector2 defaultValue, Vector2 min, Vector2 max) | |
{ | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
GUILayout.Label(label ?? key); | |
var v = Get(key); | |
using (var vs = new GUILayout.VerticalScope()) | |
{ | |
v.x = GUIUtil.Slider(v.x, min.x, max.x, "x"); | |
v.y = GUIUtil.Slider(v.y, min.y, max.y, "y"); | |
} | |
GUILayout.FlexibleSpace(); | |
Set(key, v); | |
} | |
} | |
public static void OnGUI(string key, string label = null, Vector2 defaultValue = default(Vector2)) | |
{ | |
using (var h = new GUILayout.HorizontalScope()) | |
{ | |
GUILayout.Label(label ?? key); | |
PlayerPrefs<float>.OnGUI(key + POSTFIX_X, "", defaultValue.x); | |
PlayerPrefs<float>.OnGUI(key + POSTFIX_Y, "", defaultValue.y); | |
} | |
} | |
public static Vector2 Get(string key, Vector2 defaultValue = default(Vector2)) | |
{ | |
var ret = default(Vector2); | |
ret.x = PlayerPrefs<float>.Get(key + POSTFIX_X, defaultValue.x); | |
ret.y = PlayerPrefs<float>.Get(key + POSTFIX_Y, defaultValue.y); | |
return ret; | |
} | |
public static void Set(string key, Vector2 val) | |
{ | |
PlayerPrefs<float>.Set(key + POSTFIX_X, val.x); | |
PlayerPrefs<float>.Set(key + POSTFIX_Y, val.y); | |
} | |
public static void DeleteKey(string key) | |
{ | |
PlayerPrefs.DeleteKey(key + POSTFIX_X); | |
PlayerPrefs.DeleteKey(key + POSTFIX_Y); | |
} | |
} | |
public static class PlayerPrefs<T> | |
{ | |
public static void OnGUI(string key, string label = null, T defaultValue = default(T)) | |
{ | |
if (!PlayerPrefs.HasKey(key)) Set(key, defaultValue); | |
Set(key, GUIUtil.Field<T>(Get(key), label ?? key)); | |
} | |
static System.Type type | |
{ | |
get | |
{ | |
return (typeof(T) == typeof(bool) || typeof(T).IsEnum) | |
? typeof(int) | |
: typeof(T); | |
} | |
} | |
static readonly Dictionary<Type, string> GetMethodTable = new Dictionary<Type, string> | |
{ | |
{typeof(int), "GetInt"} | |
,{typeof(float), "GetFloat"} | |
,{typeof(string), "GetString"} | |
}; | |
static readonly Dictionary<Type, string> SetMethodTable = new Dictionary<Type, string> | |
{ | |
{typeof(int), "SetInt"} | |
,{typeof(float), "SetFloat"} | |
,{typeof(string), "SetString"} | |
}; | |
public static T Get(string key, T defaultValue = default(T)) | |
{ | |
if (!PlayerPrefs.HasKey(key)) Set(key, defaultValue); | |
System.Reflection.MethodInfo info = typeof(PlayerPrefs).GetMethod(GetMethodTable[type], new[] { typeof(string) }); | |
return typeof(T).IsEnum | |
? (T)info.Invoke(null, new[] { key }) | |
: (T)Convert.ChangeType(info.Invoke(null, new[] { key }), typeof(T)); | |
} | |
public static void Set(string key, T val) | |
{ | |
System.Reflection.MethodInfo info = typeof(PlayerPrefs).GetMethod(SetMethodTable[type], new[] { typeof(string), type }); | |
info.Invoke(null, new object[] { key, Convert.ChangeType(val, type) }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment