VFXBitField.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. using UnityEditor.UIElements;
  4. using System.Collections.Generic;
  5. using System.Runtime.InteropServices;
  6. namespace UnityEditor.VFX
  7. {
  8. class BitFieldAttribute : System.Attribute
  9. {
  10. }
  11. }
  12. namespace UnityEditor.VFX.UI
  13. {
  14. abstract class VFXBitField<T, U> : VFXControl<U>
  15. {
  16. protected VisualElement[] m_Buttons;
  17. protected VisualElement m_Background;
  18. protected Texture2D m_BitImage;
  19. protected Texture2D m_BitBkgndImage;
  20. protected Label m_Label;
  21. public VFXBitField()
  22. {
  23. m_Buttons = new VisualElement[Marshal.SizeOf(typeof(T)) * 8];
  24. m_Background = new VisualElement() { name = "background" };
  25. m_Label = new Label() { name = "tip" };
  26. Add(m_Label);
  27. Add(m_Background);
  28. var buttonContainer = new VisualElement() { name = "button-container", pickingMode = PickingMode.Ignore };
  29. Add(buttonContainer);
  30. for (int i = 0; i < m_Buttons.Length; ++i)
  31. {
  32. var button = new VisualElement();
  33. button.style.flexGrow = button.style.flexShrink = 1;
  34. button.style.marginRight = 1;
  35. SetupListener(button, i);
  36. buttonContainer.Add(button);
  37. m_Buttons[i] = button;
  38. }
  39. VisualElement backgroundItem = null;
  40. for (int i = 0; i < m_Buttons.Length; ++i)
  41. {
  42. backgroundItem = new VisualElement();
  43. backgroundItem.style.flexGrow = backgroundItem.style.flexShrink = 1;
  44. if (i != m_Buttons.Length - 1)
  45. backgroundItem.style.paddingLeft = 1;
  46. SetupBkgnd(backgroundItem, i);
  47. m_Background.Add(backgroundItem);
  48. }
  49. m_Buttons[m_Buttons.Length - 1].style.marginRight = 0;
  50. RegisterCallback<CustomStyleResolvedEvent>(OnCustomStyleResolved);
  51. this.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu));
  52. }
  53. public void BuildContextualMenu(ContextualMenuPopulateEvent evt)
  54. {
  55. evt.menu.AppendAction("Check All", CheckAll, DropdownMenuAction.AlwaysEnabled);
  56. evt.menu.AppendAction("Check None", CheckNone, DropdownMenuAction.AlwaysEnabled);
  57. }
  58. protected abstract void CheckAll(DropdownMenuAction a);
  59. protected abstract void CheckNone(DropdownMenuAction a);
  60. void SetupListener(VisualElement button, int index)
  61. {
  62. button.AddManipulator(new Clickable(() => ValueToggled(index)));
  63. button.RegisterCallback<MouseEnterEvent>(e => m_Label.text = index.ToString());
  64. button.RegisterCallback<MouseLeaveEvent>(e => m_Label.text = "");
  65. }
  66. void SetupBkgnd(VisualElement button, int index)
  67. {
  68. button.RegisterCallback<MouseEnterEvent>(e => m_Label.text = index.ToString());
  69. button.RegisterCallback<MouseLeaveEvent>(e => m_Label.text = "");
  70. }
  71. protected abstract void ValueToggled(int i);
  72. static readonly CustomStyleProperty<Texture2D> s_BitImage = new CustomStyleProperty<Texture2D>("--bit-image");
  73. static readonly CustomStyleProperty<Texture2D> s_BitBkgndImage = new CustomStyleProperty<Texture2D>("--bit-bkgnd-image");
  74. private void OnCustomStyleResolved(CustomStyleResolvedEvent e)
  75. {
  76. var customStyle = e.customStyle;
  77. customStyle.TryGetValue(s_BitImage, out m_BitImage);
  78. customStyle.TryGetValue(s_BitBkgndImage, out m_BitBkgndImage);
  79. for (int i = 0; i < m_Background.childCount - 1; ++i)
  80. m_Background.ElementAt(i).style.backgroundImage = m_BitBkgndImage;
  81. ValueToGUI(true);
  82. }
  83. bool m_Indeterminate;
  84. public override bool indeterminate
  85. {
  86. get
  87. {
  88. return m_Indeterminate;
  89. }
  90. set
  91. {
  92. m_Indeterminate = value;
  93. foreach (var button in m_Buttons)
  94. {
  95. button.visible = !m_Indeterminate;
  96. }
  97. }
  98. }
  99. }
  100. class VFX32BitField : VFXBitField<uint, long>
  101. {
  102. protected override void ValueToGUI(bool force)
  103. {
  104. uint value = (uint)this.value;
  105. for (int i = 0; i < m_Buttons.Length; ++i)
  106. {
  107. m_Buttons[i].style.backgroundImage = (value & 1u << i) != 0 ? m_BitImage : null;
  108. }
  109. }
  110. protected override void ValueToggled(int i)
  111. {
  112. value = value ^ (1u << i);
  113. }
  114. protected override void CheckAll(DropdownMenuAction a)
  115. {
  116. value = 0xFFFFFFFF;
  117. }
  118. protected override void CheckNone(DropdownMenuAction a)
  119. {
  120. value = 0;
  121. }
  122. }
  123. }