You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
6.9 KiB
184 lines
6.9 KiB
//========= Copyright 2016-2019, HTC Corporation. All rights reserved. ===========
|
|
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace HTC.UnityPlugin.Utility
|
|
{
|
|
[CustomPropertyDrawer(typeof(FlagsFromEnumAttribute))]
|
|
[CanEditMultipleObjects]
|
|
public class FlagsFromEnumAttributeDrawer : PropertyDrawer
|
|
{
|
|
private static GUIStyle s_popup;
|
|
private static GUIContent s_tempContent;
|
|
private static List<bool> s_displayedMask;
|
|
|
|
private bool m_foldoutOpen = false;
|
|
|
|
static FlagsFromEnumAttributeDrawer()
|
|
{
|
|
s_popup = new GUIStyle(EditorStyles.popup);
|
|
s_tempContent = new GUIContent();
|
|
s_displayedMask = new List<bool>();
|
|
}
|
|
|
|
private bool TryGetEnumInfo(out EnumUtils.EnumDisplayInfo info)
|
|
{
|
|
var ffeAttribute = attribute as FlagsFromEnumAttribute;
|
|
|
|
if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
|
|
{
|
|
info = null;
|
|
return false;
|
|
}
|
|
|
|
info = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
|
|
return info != null;
|
|
}
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
{
|
|
EnumUtils.EnumDisplayInfo enumInfo;
|
|
|
|
if (!m_foldoutOpen || !TryGetEnumInfo(out enumInfo))
|
|
{
|
|
return EditorGUIUtility.singleLineHeight;
|
|
}
|
|
else
|
|
{
|
|
return EditorGUIUtility.singleLineHeight * (enumInfo.displayedMaskNames.Length + 2);
|
|
}
|
|
}
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
EditorGUI.BeginProperty(position, label, property);
|
|
|
|
EnumUtils.EnumDisplayInfo enumInfo;
|
|
|
|
if (property.propertyType != SerializedPropertyType.Integer)
|
|
{
|
|
EditorGUI.LabelField(position, label.text, "Use FlagFromEnum with integer.");
|
|
}
|
|
else if (!TryGetEnumInfo(out enumInfo))
|
|
{
|
|
EditorGUI.LabelField(position, label.text, "Set FlagFromEnum argument with enum type.");
|
|
}
|
|
else
|
|
{
|
|
position = EditorGUI.PrefixLabel(position, new GUIContent(property.displayName));
|
|
|
|
// get display mask value
|
|
s_displayedMask.Clear();
|
|
var enumDisplayLength = enumInfo.displayedMaskLength;
|
|
var realMask = (ulong)property.longValue;
|
|
var firstSelected = string.Empty;
|
|
for (int i = 0; i < enumDisplayLength; ++i)
|
|
{
|
|
if (EnumUtils.GetFlag(realMask, enumInfo.displayedMaskValues[i]))
|
|
{
|
|
s_displayedMask.Add(true);
|
|
if (string.IsNullOrEmpty(firstSelected)) { firstSelected = enumInfo.displayedMaskNames[i]; }
|
|
}
|
|
else
|
|
{
|
|
s_displayedMask.Add(false);
|
|
}
|
|
}
|
|
|
|
var flagsCount = 0;
|
|
for (var i = 0; i < EnumUtils.ULONG_MASK_FIELD_LENGTH; ++i)
|
|
{
|
|
if (EnumUtils.GetFlag(realMask, i)) { ++flagsCount; }
|
|
}
|
|
|
|
if (EditorGUI.showMixedValue)
|
|
{
|
|
s_tempContent.text = " - ";
|
|
}
|
|
else if (flagsCount == 0)
|
|
{
|
|
s_tempContent.text = "None";
|
|
}
|
|
else if (flagsCount == 1)
|
|
{
|
|
s_tempContent.text = firstSelected;
|
|
}
|
|
else if (flagsCount < enumDisplayLength)
|
|
{
|
|
s_tempContent.text = "Mixed...";
|
|
}
|
|
else
|
|
{
|
|
s_tempContent.text = "All";
|
|
}
|
|
|
|
var controlPos = position;
|
|
controlPos.height = EditorGUIUtility.singleLineHeight;
|
|
var id = GUIUtility.GetControlID(FocusType.Passive, controlPos);
|
|
|
|
switch (Event.current.GetTypeForControl(id))
|
|
{
|
|
case EventType.MouseDown:
|
|
if (controlPos.Contains(Event.current.mousePosition))
|
|
{
|
|
GUIUtility.hotControl = id;
|
|
GUIUtility.keyboardControl = id;
|
|
Event.current.Use();
|
|
}
|
|
break;
|
|
case EventType.MouseUp:
|
|
if (GUIUtility.hotControl == id)
|
|
{
|
|
GUIUtility.hotControl = 0;
|
|
GUIUtility.keyboardControl = 0;
|
|
Event.current.Use();
|
|
m_foldoutOpen = !m_foldoutOpen;
|
|
}
|
|
break;
|
|
case EventType.Repaint:
|
|
s_popup.Draw(position, s_tempContent, id, false);
|
|
break;
|
|
}
|
|
|
|
if (m_foldoutOpen)
|
|
{
|
|
position.y += EditorGUIUtility.singleLineHeight;
|
|
|
|
var halfWidth = position.width * 0.5f;
|
|
if (GUI.Button(new Rect(position.x, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "All"))
|
|
{
|
|
realMask = System.Runtime.InteropServices.Marshal.SizeOf(fieldInfo.FieldType) < sizeof(ulong) ? ~0u : ~0ul;
|
|
//m_foldoutOpen = false;
|
|
}
|
|
|
|
//Draw the None button
|
|
if (GUI.Button(new Rect(position.x + halfWidth + 1, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "None"))
|
|
{
|
|
realMask = 0ul;
|
|
//m_foldoutOpen = false;
|
|
}
|
|
|
|
for (int i = 0; i < enumDisplayLength; ++i)
|
|
{
|
|
position.y += EditorGUIUtility.singleLineHeight;
|
|
var toggled = EditorGUI.ToggleLeft(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), enumInfo.displayedMaskNames[i], s_displayedMask[i]);
|
|
if (s_displayedMask[i] != toggled)
|
|
{
|
|
s_displayedMask[i] = toggled;
|
|
EnumUtils.SetFlag(ref realMask, enumInfo.displayedMaskValues[i], toggled);
|
|
//m_foldoutOpen = false;
|
|
}
|
|
}
|
|
|
|
property.longValue = (long)realMask;
|
|
}
|
|
}
|
|
|
|
property.serializedObject.ApplyModifiedProperties();
|
|
|
|
EditorGUI.EndProperty();
|
|
}
|
|
}
|
|
}
|