ScrollViewEditor.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // -----------------------------------------------------------------------
  2. // <copyright file="ScrollViewEditor.cs" company="AillieoTech">
  3. // Copyright (c) AillieoTech. All rights reserved.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. namespace TapSDK.UI.AillieoTech
  7. {
  8. using System;
  9. using System.Linq;
  10. using System.Reflection;
  11. using UnityEditor;
  12. using UnityEditor.UI;
  13. using UnityEngine;
  14. using UnityEngine.UI;
  15. [CustomEditor(typeof(ScrollView))]
  16. public class ScrollViewEditor : ScrollRectEditor
  17. {
  18. private const string bgPath = "UI/Skin/Background.psd";
  19. private const string spritePath = "UI/Skin/UISprite.psd";
  20. private const string maskPath = "UI/Skin/UIMask.psd";
  21. private static Color panelColor = new Color(1f, 1f, 1f, 0.392f);
  22. private static Color defaultSelectableColor = new Color(1f, 1f, 1f, 1f);
  23. private static Vector2 thinElementSize = new Vector2(160f, 20f);
  24. private static Action<GameObject, MenuCommand> PlaceUIElementRoot;
  25. private SerializedProperty itemTemplate;
  26. private SerializedProperty poolSize;
  27. private SerializedProperty defaultItemSize;
  28. private SerializedProperty layoutType;
  29. private GUIStyle cachedCaption;
  30. private GUIStyle caption
  31. {
  32. get
  33. {
  34. if (this.cachedCaption == null)
  35. {
  36. this.cachedCaption = new GUIStyle { richText = true, alignment = TextAnchor.MiddleCenter };
  37. }
  38. return this.cachedCaption;
  39. }
  40. }
  41. public override void OnInspectorGUI()
  42. {
  43. this.serializedObject.Update();
  44. EditorGUILayout.BeginVertical("box");
  45. EditorGUILayout.LabelField("<b>Additional configs</b>", this.caption);
  46. EditorGUILayout.Space();
  47. this.DrawConfigInfo();
  48. this.serializedObject.ApplyModifiedProperties();
  49. EditorGUILayout.EndVertical();
  50. EditorGUILayout.BeginVertical("box");
  51. EditorGUILayout.LabelField("<b>For original ScrollRect</b>", this.caption);
  52. EditorGUILayout.Space();
  53. base.OnInspectorGUI();
  54. EditorGUILayout.EndVertical();
  55. }
  56. protected static void InternalAddScrollView<T>(MenuCommand menuCommand)
  57. where T : ScrollView
  58. {
  59. GetPrivateMethodByReflection();
  60. GameObject root = CreateUIElementRoot(typeof(T).Name, new Vector2(200, 200));
  61. PlaceUIElementRoot?.Invoke(root, menuCommand);
  62. GameObject viewport = CreateUIObject("Viewport", root);
  63. GameObject content = CreateUIObject("Content", viewport);
  64. var parent = menuCommand.context as GameObject;
  65. if (parent != null)
  66. {
  67. root.transform.SetParent(parent.transform, false);
  68. }
  69. Selection.activeGameObject = root;
  70. GameObject hScrollbar = CreateScrollbar();
  71. hScrollbar.name = "Scrollbar Horizontal";
  72. hScrollbar.transform.SetParent(root.transform, false);
  73. RectTransform hScrollbarRT = hScrollbar.GetComponent<RectTransform>();
  74. hScrollbarRT.anchorMin = Vector2.zero;
  75. hScrollbarRT.anchorMax = Vector2.right;
  76. hScrollbarRT.pivot = Vector2.zero;
  77. hScrollbarRT.sizeDelta = new Vector2(0, hScrollbarRT.sizeDelta.y);
  78. GameObject vScrollbar = CreateScrollbar();
  79. vScrollbar.name = "Scrollbar Vertical";
  80. vScrollbar.transform.SetParent(root.transform, false);
  81. vScrollbar.GetComponent<Scrollbar>().SetDirection(Scrollbar.Direction.BottomToTop, true);
  82. RectTransform vScrollbarRT = vScrollbar.GetComponent<RectTransform>();
  83. vScrollbarRT.anchorMin = Vector2.right;
  84. vScrollbarRT.anchorMax = Vector2.one;
  85. vScrollbarRT.pivot = Vector2.one;
  86. vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0);
  87. RectTransform viewportRect = viewport.GetComponent<RectTransform>();
  88. viewportRect.anchorMin = Vector2.zero;
  89. viewportRect.anchorMax = Vector2.one;
  90. viewportRect.sizeDelta = Vector2.zero;
  91. viewportRect.pivot = Vector2.up;
  92. RectTransform contentRect = content.GetComponent<RectTransform>();
  93. contentRect.anchorMin = Vector2.up;
  94. contentRect.anchorMax = Vector2.one;
  95. contentRect.sizeDelta = new Vector2(0, 300);
  96. contentRect.pivot = Vector2.up;
  97. ScrollView scrollRect = root.AddComponent<T>();
  98. scrollRect.content = contentRect;
  99. scrollRect.viewport = viewportRect;
  100. scrollRect.horizontalScrollbar = hScrollbar.GetComponent<Scrollbar>();
  101. scrollRect.verticalScrollbar = vScrollbar.GetComponent<Scrollbar>();
  102. scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
  103. scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
  104. scrollRect.horizontalScrollbarSpacing = -3;
  105. scrollRect.verticalScrollbarSpacing = -3;
  106. Image rootImage = root.AddComponent<Image>();
  107. rootImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath);
  108. rootImage.type = Image.Type.Sliced;
  109. rootImage.color = panelColor;
  110. Mask viewportMask = viewport.AddComponent<Mask>();
  111. viewportMask.showMaskGraphic = false;
  112. Image viewportImage = viewport.AddComponent<Image>();
  113. viewportImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(maskPath);
  114. viewportImage.type = Image.Type.Sliced;
  115. }
  116. protected override void OnEnable()
  117. {
  118. base.OnEnable();
  119. this.itemTemplate = this.serializedObject.FindProperty("itemTemplate");
  120. this.poolSize = this.serializedObject.FindProperty("poolSize");
  121. this.defaultItemSize = this.serializedObject.FindProperty("defaultItemSize");
  122. this.layoutType = this.serializedObject.FindProperty("layoutType");
  123. }
  124. protected virtual void DrawConfigInfo()
  125. {
  126. EditorGUILayout.PropertyField(this.itemTemplate);
  127. EditorGUILayout.PropertyField(this.poolSize);
  128. EditorGUILayout.PropertyField(this.defaultItemSize);
  129. this.layoutType.intValue = (int)(ScrollView.ItemLayoutType)EditorGUILayout.EnumPopup("layoutType", (ScrollView.ItemLayoutType)this.layoutType.intValue);
  130. }
  131. [MenuItem("GameObject/UI/DynamicScrollView", false, 90)]
  132. private static void AddScrollView(MenuCommand menuCommand)
  133. {
  134. InternalAddScrollView<ScrollView>(menuCommand);
  135. }
  136. private static GameObject CreateScrollbar()
  137. {
  138. // Create GOs Hierarchy
  139. GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", thinElementSize);
  140. GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot);
  141. GameObject handle = CreateUIObject("Handle", sliderArea);
  142. Image bgImage = scrollbarRoot.AddComponent<Image>();
  143. bgImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath);
  144. bgImage.type = Image.Type.Sliced;
  145. bgImage.color = defaultSelectableColor;
  146. Image handleImage = handle.AddComponent<Image>();
  147. handleImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(spritePath);
  148. handleImage.type = Image.Type.Sliced;
  149. handleImage.color = defaultSelectableColor;
  150. RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>();
  151. sliderAreaRect.sizeDelta = new Vector2(-20, -20);
  152. sliderAreaRect.anchorMin = Vector2.zero;
  153. sliderAreaRect.anchorMax = Vector2.one;
  154. RectTransform handleRect = handle.GetComponent<RectTransform>();
  155. handleRect.sizeDelta = new Vector2(20, 20);
  156. Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>();
  157. scrollbar.handleRect = handleRect;
  158. scrollbar.targetGraphic = handleImage;
  159. SetDefaultColorTransitionValues(scrollbar);
  160. return scrollbarRoot;
  161. }
  162. private static GameObject CreateUIElementRoot(string name, Vector2 size)
  163. {
  164. var child = new GameObject(name);
  165. RectTransform rectTransform = child.AddComponent<RectTransform>();
  166. rectTransform.sizeDelta = size;
  167. return child;
  168. }
  169. private static GameObject CreateUIObject(string name, GameObject parent)
  170. {
  171. var go = new GameObject(name);
  172. go.AddComponent<RectTransform>();
  173. SetParentAndAlign(go, parent);
  174. return go;
  175. }
  176. private static void SetParentAndAlign(GameObject child, GameObject parent)
  177. {
  178. if (parent == null)
  179. {
  180. return;
  181. }
  182. child.transform.SetParent(parent.transform, false);
  183. SetLayerRecursively(child, parent.layer);
  184. }
  185. private static void SetLayerRecursively(GameObject go, int layer)
  186. {
  187. go.layer = layer;
  188. Transform t = go.transform;
  189. for (var i = 0; i < t.childCount; i++)
  190. {
  191. SetLayerRecursively(t.GetChild(i).gameObject, layer);
  192. }
  193. }
  194. private static void SetDefaultColorTransitionValues(Selectable slider)
  195. {
  196. ColorBlock colors = slider.colors;
  197. colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
  198. colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
  199. colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
  200. }
  201. private static void GetPrivateMethodByReflection()
  202. {
  203. if (PlaceUIElementRoot == null)
  204. {
  205. Assembly uiEditorAssembly = AppDomain.CurrentDomain.GetAssemblies()
  206. .FirstOrDefault(asm => asm.GetName().Name == "UnityEditor.UI");
  207. if (uiEditorAssembly != null)
  208. {
  209. Type menuOptionType = uiEditorAssembly.GetType("UnityEditor.UI.MenuOptions");
  210. if (menuOptionType != null)
  211. {
  212. MethodInfo miPlaceUIElementRoot = menuOptionType.GetMethod(
  213. "PlaceUIElementRoot",
  214. BindingFlags.NonPublic | BindingFlags.Static);
  215. if (miPlaceUIElementRoot != null)
  216. {
  217. PlaceUIElementRoot = Delegate.CreateDelegate(
  218. typeof(Action<GameObject, MenuCommand>),
  219. miPlaceUIElementRoot)
  220. as Action<GameObject, MenuCommand>;
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }