Skip to content

Instantly share code, notes, and snippets.

@fuqunaga
Last active February 23, 2016 08:40
Show Gist options
  • Save fuqunaga/3c7adee2e7b732c82512 to your computer and use it in GitHub Desktop.
Save fuqunaga/3c7adee2e7b732c82512 to your computer and use it in GitHub Desktop.
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