-AUTEUR: artemisart
-DESCRIPTION :
Cette classe est un portage presque complet de la classe EditorGUI (toutes les fonctions ont été recodées à part DisabledGroup et ChangeCheck (merci ILSpy )).
- Fonctions utilisables : L'utilisation est extrêmement similaire à EditorGUI.
- Créer un groupe désactivable :
- void BeginDisabledGroup (bool disabled)
- void EndDisabledGroup ()
- Vérifie si un contrôle a été modifié à l'intérieur d'un bloc de code.
- void BeginChangeCheck ()
- bool EndChangeCheck ()
- édition d'int
- int IntField (Rect rect, int value)
- édition de float, peut accepter les valeurs infinies (par défaut non), écriture normale ou scientifique
- float FloatField (Rect rect, float value)
- float FloatField (Rect rect, float value, bool allowInfinity)
- édition de Vector, yOffset est l'offset en pixels entre les différents FloatFields (x, y, z)
- Vector2/3/4 VectorField (Rect rect, Vector2/3/4 value)
- Vector2/3/4 VectorField (Rect rect, Vector2/3/4 value, float yOffset)
doc : http://docs.unity3d.com/Documentation/S ... Field.html, http://docs.unity3d.com/Documentation/S ... Field.html, http://docs.unity3d.com/Documentation/S ... Field.html
- édition de Rect, idem pour yOffset
- Rect RectField (Rect rect, Rect value)
- Rect RectField (Rect rect, Rect value, float yOffset)
- édition de Bounds, idem pour yOffset
- Bounds BoundsField (Rect rect, Bounds value)
- Bounds BoundsField (Rect rect, Bounds value, float yOffset)
- sélection dans une liste, selectedIndex est l'option actuellement sélectionné et displayedOptions est la liste des options. selectionHighlight est le caractère utilisé pour indiquer la sélection (par défaut ►).
- int Popup (Rect rect, int selectedIndex, string[] displayedOptions)
- int Popup (Rect rect, int selectedIndex, string[] displayedOptions, char selectionHighlight)
- sélection dans un enum, T doit être un enum, la fonction est générique seulement pour éviter à l'utilisateur de convertir le retour de la fonction.
- T EnumPopup<T> (Rect rect, T selected)
- multisélection dans une liste (bitfield), mask est le bitfield displayedOptions est la liste des options. selectionHighlight est le caractère utilisé pour indiquer la sélection (par défaut ►).
- int MaskField (Rect rect, int mask, string[] displayedOptions)
- int MaskField (Rect rect, int mask, string[] displayedOptions, char selectionHighlight)
- multisélection dans un enum, T doit être un enum, la fonction est générique seulement pour éviter à l'utilisateur de convertir le retour de la fonction.
- T EnumMaskField<T> (Rect rect, T mask)
Dans le cas où plusieurs champs sont affichés, (toutes les fonctions sauf IntField et FloatField), le paramètre rect est le rectangle utilisé pour le premier champ, et non l'ensemble.
Dans le IntField, on peut rentrer juste des chiffres, et l'appui sur la touche "-" inverse le signe du nombre.
Exemple : si on entre "54-", le nombre sera "-54", et si on ré-appui sur "-" (ce qui donne "-54-") le nombre sera 54.
Dans le FloatField, c'est pareil, la touche - inverse le signe du nombre, + les virgules sont transformés en points et on peut autoriser l'utilisateur à entrer l'infini (bool allowInfinity) (et la casse est ignorée).
Quelques exemples :
- "0.1", ".1", "0,1" et ",1" donnent 0.1f
- "inf" et "infinity" donnent float.PositiveInfinity / Mathf.Infinity
- "-inf" et "-infinity" donnent float.NegativeInfinity / Mathf.NegativeInfinity
- "1e3" et "1e+3" donnent 1000
- "1e-3" donne 0.001f
-UTILISATION :
Exemple :
Code : Tout sélectionner
using UnityEngine;
public class xGUItest : MonoBehaviour
{
[System.Flags]
public enum MyEnum
{
first,
second,
third,
last
}
public bool disabled = false;
public int myInt = 0;
public float myFloat = 0;
public float myFloatAllowInfinity = 0;
public Vector4 myVector;
public Rect myRect;
public Bounds myBounds;
public int mySelected;
public int myFlags;
public string[] myOptions = { "haha", "truc", "bidule" };
public MyEnum myEnum;
public MyEnum myEnumFlags;
void OnGUI ()
{
xGUI.BeginChangeCheck ();
xGUI.BeginDisabledGroup (disabled);
DrawGUI ();
xGUI.EndDisabledGroup ();
if (xGUI.EndChangeCheck ())
print ("changed");
}
void DrawGUI ()
{
myInt = xGUI.IntField (new Rect (10, 10, 100, 20), myInt);
myFloat = xGUI.FloatField (new Rect (10, 40, 100, 20), myFloat);
myFloatAllowInfinity = xGUI.FloatField (new Rect (10, 70, 100, 20), myFloatAllowInfinity, true);
myVector = xGUI.VectorField (new Rect (10, 100, 100, 20), myVector);
myRect = xGUI.RectField (new Rect (10, 190, 100, 20), myRect);
myBounds = xGUI.BoundsField (new Rect (120, 10, 100, 20), myBounds);
mySelected = xGUI.Popup (new Rect (230, 10, 100, 20), mySelected, myOptions);
myEnum = xGUI.EnumPopup (new Rect (230, 100, 100, 20), myEnum);
myFlags = xGUI.MaskField (new Rect (230, 200, 100, 20), myFlags, myOptions);
myEnumFlags = xGUI.EnumMaskField (new Rect (230, 330, 100, 20), myEnumFlags);
}
}
Code : Tout sélectionner
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public static class xGUI
{
private static Texture error_tex = null;
private static Stack<bool> enabledStack = new Stack<bool> ();
private static Stack<bool> changedStack = new Stack<bool> ();
private static string currentEditingString = "empty";
private static string lastFocusedControl;
private static void Load ()
{
if (error_tex == null)
error_tex = Resources.Load ("Textures/error") as Texture;
}
private static string GetHash (string a, Rect b)
{
return string.Format ("xGUI{0}{1}{2}{3}{4}", a, b.x, b.y, b.width, b.height);
}
private static void SetCES (object value)
{
if (currentEditingString == "empty")
currentEditingString = value.ToString ();
}
private static bool HasFocus (string hash)
{
if ((hash.StartsWith ("xGUIPopup") || hash.StartsWith ("xGUIMaskField")) && lastFocusedControl == hash)
return true;
if (GUI.GetNameOfFocusedControl () == hash)
{
if (lastFocusedControl != hash)
currentEditingString = "empty";
lastFocusedControl = hash;
return true;
}
return false;
}
private static void NumberTextField (Rect rect, bool isFloat)
{
currentEditingString = GUI.TextField (rect, currentEditingString).ToLower ();
if (isFloat)
currentEditingString = currentEditingString.Replace (',', '.');
currentEditingString = new string (currentEditingString
.Where (c => (isFloat ? "inftye0123456789.+-" : "0123456789-").Contains (c))
.ToArray ()
);
if (currentEditingString.Length > 1 && currentEditingString.EndsWith ("-") && !currentEditingString.EndsWith ("e-"))
{
if (currentEditingString[0] == '-')
currentEditingString = currentEditingString.Substring (1, currentEditingString.Length - 2);
else
currentEditingString = "-" + currentEditingString.Substring (0, currentEditingString.Length - 1);
}
}
public static void BeginDisabledGroup (bool disabled)
{
enabledStack.Push (GUI.enabled);
GUI.enabled &= !disabled;
}
public static void EndDisabledGroup ()
{
GUI.enabled = enabledStack.Pop ();
}
public static void BeginChangeCheck ()
{
changedStack.Push (GUI.changed);
GUI.changed = false;
}
public static bool EndChangeCheck ()
{
bool changed = GUI.changed;
GUI.changed |= changedStack.Pop ();
return changed;
}
public static int IntField (Rect rect, int value)
{
string hash = GetHash ("IntField", rect);
GUI.SetNextControlName (hash);
if (HasFocus (hash))
{
SetCES (value);
NumberTextField (rect, false);
int temp;
if (int.TryParse (currentEditingString, out temp))
value = temp;
}
else
GUI.TextField (rect, value.ToString ());
return value;
}
public static float FloatField (Rect rect, float value)
{
return FloatField (rect, value, false);
}
public static float FloatField (Rect rect, float value, bool allowInfinity)
{
Load ();
string hash = GetHash ("FloatField", rect);
GUI.SetNextControlName (hash);
if (HasFocus (hash))
{
SetCES (value);
NumberTextField (rect, true);
if (allowInfinity)
{
if (currentEditingString == "inf" || currentEditingString == "infinity")
return float.PositiveInfinity;
if (currentEditingString == "-inf" || currentEditingString == "-infinity")
return float.NegativeInfinity;
}
float temp;
if (float.TryParse (currentEditingString, out temp))
value = temp;
else
GUI.DrawTexture (new Rect (rect.x + rect.width - 20, rect.y + 2, 16, 16), error_tex);
}
else
GUI.TextField (rect, value.ToString ());
return value;
}
public static Vector2 VectorField (Rect rect, Vector2 value) { return VectorField (rect, value, 20); }
public static Vector2 VectorField (Rect rect, Vector2 value, float yOffset)
{
for (int i = 0; i < 2; i++)
{
value[i] = FloatField (rect, value[i]);
rect.y += yOffset;
}
return value;
}
public static Vector3 VectorField (Rect rect, Vector3 value) { return VectorField (rect, value, 20); }
public static Vector3 VectorField (Rect rect, Vector3 value, float yOffset)
{
for (int i = 0; i < 3; i++)
{
value[i] = FloatField (rect, value[i]);
rect.y += yOffset;
}
return value;
}
public static Vector4 VectorField (Rect rect, Vector4 value) { return VectorField (rect, value, 20); }
public static Vector4 VectorField (Rect rect, Vector4 value, float yOffset)
{
for (int i = 0; i < 4; i++)
{
value[i] = FloatField (rect, value[i]);
rect.y += yOffset;
}
return value;
}
public static Rect RectField (Rect rect, Rect value) { return RectField (rect, value, 20); }
public static Rect RectField (Rect rect, Rect value, float yOffset)
{
value.x = FloatField (rect, value.x);
rect.y += yOffset;
value.y = FloatField (rect, value.y);
rect.y += yOffset;
value.width = FloatField (rect, value.width);
rect.y += yOffset;
value.height = FloatField (rect, value.height);
return value;
}
public static Bounds BoundsField (Rect rect, Bounds value) { return BoundsField (rect, value, 20); }
public static Bounds BoundsField (Rect rect, Bounds value, float yOffset)
{
GUI.Label (rect, "Center");
rect.y += yOffset;
value.center = VectorField (rect, value.center, yOffset);
rect.y += yOffset * 3;
GUI.Label (rect, "Extents");
rect.y += yOffset;
value.extents = VectorField (rect, value.extents, yOffset);
return value;
}
public static int Popup (Rect rect, int selectedIndex, string[] displayedOptions) { return Popup (rect, selectedIndex, displayedOptions, '►'); }
public static int Popup (Rect rect, int selectedIndex, string[] displayedOptions, char selectionHighlight)
{
string hash = GetHash ("Popup", rect);
GUI.SetNextControlName (hash);
if (HasFocus (hash))
{
GUI.Button (rect, displayedOptions[selectedIndex]);
int height = 18 * displayedOptions.Length + 2;
if (Event.current.type == EventType.MouseDown &&
!new Rect (rect.x, rect.y, rect.width, rect.height + height).Contains (Event.current.mousePosition))
{
lastFocusedControl = "";
return selectedIndex;
}
rect.y += rect.height;
GUI.Box (new Rect (rect.x, rect.y, rect.width, height), "");
rect.x += 5;
rect.width -= 5;
for (int i = 0; i < displayedOptions.Length; i++)
{
if (selectedIndex == i)
GUI.Label (rect, selectionHighlight + "\t" + displayedOptions[i]);
else if (GUI.Button (rect, "\t" + displayedOptions[i], GUI.skin.label))
selectedIndex = i;
rect.y += 18;
}
}
else if (GUI.Button (rect, displayedOptions[selectedIndex]))
lastFocusedControl = hash;
return selectedIndex;
}
public static T EnumPopup<T> (Rect rect, T selected) where T : struct, IComparable, IFormattable, IConvertible
{
Type t = typeof (T);
if (!t.IsEnum)
throw new Exception ("parameter T selected must be of type System.Enum");
return (T)Enum.Parse (t, Popup (rect, Convert.ToInt32 (selected), Enum.GetNames (t)).ToString ());
}
public static int MaskField (Rect rect, int mask, string[] displayedOptions) { return MaskField (rect, mask, displayedOptions, '►'); }
public static int MaskField (Rect rect, int mask, string[] displayedOptions, char selectionHighlight)
{
int i;
string label;
List<int> selectedIndexes = new List<int> ();
List<string> options = new List<string> { "Nothing", "Everything" };
options.AddRange (displayedOptions);
for (i = 0; i < displayedOptions.Length; i++)
if ((mask & 1 << i) > 0)
selectedIndexes.Add (i + 2);
if (selectedIndexes.Count == 0)
label = "Nothing";
else if (selectedIndexes.Count == 1)
label = options[selectedIndexes[0]];
else if (selectedIndexes.Count < displayedOptions.Length)
label = "Mixed ...";
else
{
label = "Everything";
selectedIndexes.Add (1);
}
i = 0;
int count = displayedOptions.Count (useless => (mask & 1 << i) == 1 << i++);
i = 0;
if (count == 0)
label = "Nothing";
else if (count == 1)
label = displayedOptions.First (useless => (mask & 1 << i) == 1 << i++);
else if (count < displayedOptions.Length)
label = "Mixed ...";
else
label = "Everything";
string hash = GetHash ("MaskField", rect);
GUI.SetNextControlName (hash);
if (HasFocus (hash))
{
GUI.Button (rect, label);
int height = 18 * options.Count + 2;
if (Event.current.type == EventType.MouseDown &&
!new Rect (rect.x, rect.y, rect.width, rect.height + height).Contains (Event.current.mousePosition))
{
lastFocusedControl = "";
return mask;
}
rect.y += rect.height;
GUI.Box (new Rect (rect.x, rect.y, rect.width, height), "");
rect.x += 5;
rect.width -= 5;
for (i = -2; i < displayedOptions.Length; i++)
{
if (i == -2)
{
if (count == displayedOptions.Length)
GUI.Label (rect, selectionHighlight + "\tEverything");
else if (GUI.Button (rect, "\tEverything", GUI.skin.label))
mask = -1;
}
else if (i == -1)
{
if (count == 0)
GUI.Label (rect, selectionHighlight + "\tNothing");
else if (GUI.Button (rect, "\tNothing", GUI.skin.label))
mask = 0;
}
else if (GUI.Button (rect, ((mask & 1 << i) == 1 << i ? selectionHighlight + "\t" : "\t") + displayedOptions[i], GUI.skin.label))
mask ^= 1 << i;
rect.y += 18;
}
}
else if (GUI.Button (rect, label))
lastFocusedControl = hash;
return mask;
}
public static T EnumMaskField<T> (Rect rect, T mask) where T : struct, IComparable, IFormattable, IConvertible
{
Type t = typeof (T);
if (!t.IsEnum)
throw new Exception ("parameter T mask must be of type System.Enum");
return (T)Enum.Parse (t, MaskField (rect, Convert.ToInt32 (mask), Enum.GetNames (t)).ToString ());
}
}