2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
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.

183 lines
6.9 KiB

5 years ago
  1. //========= Copyright 2016-2019, HTC Corporation. All rights reserved. ===========
  2. using System.Collections.Generic;
  3. using UnityEditor;
  4. using UnityEngine;
  5. namespace HTC.UnityPlugin.Utility
  6. {
  7. [CustomPropertyDrawer(typeof(FlagsFromEnumAttribute))]
  8. [CanEditMultipleObjects]
  9. public class FlagsFromEnumAttributeDrawer : PropertyDrawer
  10. {
  11. private static GUIStyle s_popup;
  12. private static GUIContent s_tempContent;
  13. private static List<bool> s_displayedMask;
  14. private bool m_foldoutOpen = false;
  15. static FlagsFromEnumAttributeDrawer()
  16. {
  17. s_popup = new GUIStyle(EditorStyles.popup);
  18. s_tempContent = new GUIContent();
  19. s_displayedMask = new List<bool>();
  20. }
  21. private bool TryGetEnumInfo(out EnumUtils.EnumDisplayInfo info)
  22. {
  23. var ffeAttribute = attribute as FlagsFromEnumAttribute;
  24. if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
  25. {
  26. info = null;
  27. return false;
  28. }
  29. info = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
  30. return info != null;
  31. }
  32. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  33. {
  34. EnumUtils.EnumDisplayInfo enumInfo;
  35. if (!m_foldoutOpen || !TryGetEnumInfo(out enumInfo))
  36. {
  37. return EditorGUIUtility.singleLineHeight;
  38. }
  39. else
  40. {
  41. return EditorGUIUtility.singleLineHeight * (enumInfo.displayedMaskNames.Length + 2);
  42. }
  43. }
  44. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  45. {
  46. EditorGUI.BeginProperty(position, label, property);
  47. EnumUtils.EnumDisplayInfo enumInfo;
  48. if (property.propertyType != SerializedPropertyType.Integer)
  49. {
  50. EditorGUI.LabelField(position, label.text, "Use FlagFromEnum with integer.");
  51. }
  52. else if (!TryGetEnumInfo(out enumInfo))
  53. {
  54. EditorGUI.LabelField(position, label.text, "Set FlagFromEnum argument with enum type.");
  55. }
  56. else
  57. {
  58. position = EditorGUI.PrefixLabel(position, new GUIContent(property.displayName));
  59. // get display mask value
  60. s_displayedMask.Clear();
  61. var enumDisplayLength = enumInfo.displayedMaskLength;
  62. var realMask = (ulong)property.longValue;
  63. var firstSelected = string.Empty;
  64. for (int i = 0; i < enumDisplayLength; ++i)
  65. {
  66. if (EnumUtils.GetFlag(realMask, enumInfo.displayedMaskValues[i]))
  67. {
  68. s_displayedMask.Add(true);
  69. if (string.IsNullOrEmpty(firstSelected)) { firstSelected = enumInfo.displayedMaskNames[i]; }
  70. }
  71. else
  72. {
  73. s_displayedMask.Add(false);
  74. }
  75. }
  76. var flagsCount = 0;
  77. for (var i = 0; i < EnumUtils.ULONG_MASK_FIELD_LENGTH; ++i)
  78. {
  79. if (EnumUtils.GetFlag(realMask, i)) { ++flagsCount; }
  80. }
  81. if (EditorGUI.showMixedValue)
  82. {
  83. s_tempContent.text = " - ";
  84. }
  85. else if (flagsCount == 0)
  86. {
  87. s_tempContent.text = "None";
  88. }
  89. else if (flagsCount == 1)
  90. {
  91. s_tempContent.text = firstSelected;
  92. }
  93. else if (flagsCount < enumDisplayLength)
  94. {
  95. s_tempContent.text = "Mixed...";
  96. }
  97. else
  98. {
  99. s_tempContent.text = "All";
  100. }
  101. var controlPos = position;
  102. controlPos.height = EditorGUIUtility.singleLineHeight;
  103. var id = GUIUtility.GetControlID(FocusType.Passive, controlPos);
  104. switch (Event.current.GetTypeForControl(id))
  105. {
  106. case EventType.MouseDown:
  107. if (controlPos.Contains(Event.current.mousePosition))
  108. {
  109. GUIUtility.hotControl = id;
  110. GUIUtility.keyboardControl = id;
  111. Event.current.Use();
  112. }
  113. break;
  114. case EventType.MouseUp:
  115. if (GUIUtility.hotControl == id)
  116. {
  117. GUIUtility.hotControl = 0;
  118. GUIUtility.keyboardControl = 0;
  119. Event.current.Use();
  120. m_foldoutOpen = !m_foldoutOpen;
  121. }
  122. break;
  123. case EventType.Repaint:
  124. s_popup.Draw(position, s_tempContent, id, false);
  125. break;
  126. }
  127. if (m_foldoutOpen)
  128. {
  129. position.y += EditorGUIUtility.singleLineHeight;
  130. var halfWidth = position.width * 0.5f;
  131. if (GUI.Button(new Rect(position.x, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "All"))
  132. {
  133. realMask = System.Runtime.InteropServices.Marshal.SizeOf(fieldInfo.FieldType) < sizeof(ulong) ? ~0u : ~0ul;
  134. //m_foldoutOpen = false;
  135. }
  136. //Draw the None button
  137. if (GUI.Button(new Rect(position.x + halfWidth + 1, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "None"))
  138. {
  139. realMask = 0ul;
  140. //m_foldoutOpen = false;
  141. }
  142. for (int i = 0; i < enumDisplayLength; ++i)
  143. {
  144. position.y += EditorGUIUtility.singleLineHeight;
  145. var toggled = EditorGUI.ToggleLeft(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), enumInfo.displayedMaskNames[i], s_displayedMask[i]);
  146. if (s_displayedMask[i] != toggled)
  147. {
  148. s_displayedMask[i] = toggled;
  149. EnumUtils.SetFlag(ref realMask, enumInfo.displayedMaskValues[i], toggled);
  150. //m_foldoutOpen = false;
  151. }
  152. }
  153. property.longValue = (long)realMask;
  154. }
  155. }
  156. property.serializedObject.ApplyModifiedProperties();
  157. EditorGUI.EndProperty();
  158. }
  159. }
  160. }