UIBuilder.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. using HMUI;
  2. using SongBrowserPlugin.DataAccess;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using TMPro;
  9. using UnityEngine;
  10. using UnityEngine.Events;
  11. using UnityEngine.SceneManagement;
  12. using UnityEngine.UI;
  13. using VRUI;
  14. using Image = UnityEngine.UI.Image;
  15. namespace SongBrowserPlugin.UI
  16. {
  17. public static class UIBuilder
  18. {
  19. /// <summary>
  20. /// Create an empty BeatSaber VRUI view controller.
  21. /// </summary>
  22. /// <typeparam name="T"></typeparam>
  23. /// <param name="name"></param>
  24. /// <returns></returns>
  25. public static T CreateViewController<T>(string name) where T : VRUIViewController
  26. {
  27. T vc = new GameObject(name).AddComponent<T>();
  28. vc.rectTransform.anchorMin = new Vector2(0f, 0f);
  29. vc.rectTransform.anchorMax = new Vector2(1f, 1f);
  30. vc.rectTransform.sizeDelta = new Vector2(0f, 0f);
  31. vc.rectTransform.anchoredPosition = new Vector2(0f, 0f);
  32. return vc;
  33. }
  34. /// <summary>
  35. /// Create empty FlowCoordinator
  36. /// </summary>
  37. /// <typeparam name="T"></typeparam>
  38. /// <param name="name"></param>
  39. /// <returns></returns>
  40. public static T CreateFlowCoordinator<T>(string name) where T : FlowCoordinator
  41. {
  42. T vc = new GameObject(name).AddComponent<T>();
  43. return vc;
  44. }
  45. /// <summary>
  46. /// Helper, create a UI button from template name.
  47. /// </summary>
  48. /// <param name="parent"></param>
  49. /// <param name="buttonTemplateName"></param>
  50. /// <returns></returns>
  51. static public Button CreateUIButton(RectTransform parent, String buttonTemplateName)
  52. {
  53. Button b = Resources.FindObjectsOfTypeAll<Button>().First(x => (x.name == buttonTemplateName));
  54. return CreateUIButton(parent, b);
  55. }
  56. /// <summary>
  57. /// Clone a Unity Button into a Button we control.
  58. /// </summary>
  59. /// <param name="parent"></param>
  60. /// <param name="buttonTemplate"></param>
  61. /// <param name="buttonInstance"></param>
  62. /// <returns></returns>
  63. static public Button CreateUIButton(RectTransform parent, Button buttonTemplate)
  64. {
  65. Button btn = UnityEngine.Object.Instantiate(buttonTemplate, parent, false);
  66. UnityEngine.Object.DestroyImmediate(btn.GetComponent<GameEventOnUIButtonClick>());
  67. btn.onClick = new Button.ButtonClickedEvent();
  68. btn.name = "CustomUIButton";
  69. return btn;
  70. }
  71. /// <summary>
  72. /// Very generic helper create button method.
  73. /// </summary>
  74. /// <param name="parent"></param>
  75. /// <param name="buttonTemplate"></param>
  76. /// <param name="buttonText"></param>
  77. /// <param name="x"></param>
  78. /// <param name="y"></param>
  79. /// <param name="w"></param>
  80. /// <param name="h"></param>
  81. /// <returns></returns>
  82. static public Button CreateButton(RectTransform parent, Button buttonTemplate, String buttonText, float fontSize, float x, float y, float w, float h)
  83. {
  84. Button newButton = UIBuilder.CreateUIButton(parent, buttonTemplate);
  85. newButton.interactable = true;
  86. (newButton.transform as RectTransform).anchoredPosition = new Vector2(x, y);
  87. (newButton.transform as RectTransform).sizeDelta = new Vector2(w, h);
  88. UIBuilder.SetButtonText(ref newButton, buttonText);
  89. UIBuilder.SetButtonIconEnabled(ref newButton, false);
  90. UIBuilder.SetButtonTextSize(ref newButton, fontSize);
  91. return newButton;
  92. }
  93. /// <summary>
  94. /// Generic create sort button.
  95. /// </summary>
  96. /// <param name="rect"></param>
  97. /// <param name="templateButtonName"></param>
  98. /// <param name="buttonText"></param>
  99. /// <param name="iconName"></param>
  100. /// <param name="x"></param>
  101. /// <param name="y"></param>
  102. /// <param name="w"></param>
  103. /// <param name="h"></param>
  104. /// <param name="action"></param>
  105. public static SongSortButton CreateSortButton(RectTransform parent, Button buttonTemplate, Sprite iconSprite, string buttonText, float fontSize, float x, float y, float w, float h, SongSortMode sortMode, System.Action<SongSortMode> onClickEvent)
  106. {
  107. SongSortButton sortButton = new SongSortButton();
  108. Button newButton = UIBuilder.CreateUIButton(parent, buttonTemplate);
  109. newButton.interactable = true;
  110. (newButton.transform as RectTransform).anchoredPosition = new Vector2(x, y);
  111. (newButton.transform as RectTransform).sizeDelta = new Vector2(w, h);
  112. UIBuilder.SetButtonText(ref newButton, buttonText);
  113. UIBuilder.SetButtonIconEnabled(ref newButton, false);
  114. UIBuilder.SetButtonIcon(ref newButton, iconSprite);
  115. UIBuilder.SetButtonTextSize(ref newButton, fontSize);
  116. newButton.onClick.RemoveAllListeners();
  117. newButton.onClick.AddListener(delegate ()
  118. {
  119. onClickEvent(sortMode);
  120. });
  121. sortButton.Button = newButton;
  122. sortButton.SortMode = sortMode;
  123. return sortButton;
  124. }
  125. /// <summary>
  126. /// Create a page up/down button.
  127. /// </summary>
  128. /// <param name="parent"></param>
  129. /// <param name="buttonTemplate"></param>
  130. /// <param name="iconSprite"></param>
  131. /// <param name="x"></param>
  132. /// <param name="y"></param>
  133. /// <param name="w"></param>
  134. /// <param name="h"></param>
  135. /// <param name="iconWidth"></param>
  136. /// <param name="iconHeight"></param>
  137. /// <param name="iconRotation"></param>
  138. /// <returns></returns>
  139. public static Button CreateIconButton(RectTransform parent, Button buttonTemplate, Sprite iconSprite, Vector2 pos, Vector2 size, Vector2 iconPos, Vector2 iconSize, Vector2 iconScale, float iconRotation)
  140. {
  141. Button newButton = UIBuilder.CreateUIButton(parent, buttonTemplate);
  142. newButton.interactable = true;
  143. (newButton.transform as RectTransform).anchoredPosition = new Vector2(pos.x, pos.y);
  144. (newButton.transform as RectTransform).sizeDelta = new Vector2(size.x, size.y);
  145. RectTransform iconTransform = newButton.GetComponentsInChildren<RectTransform>(true).First(c => c.name == "Icon");
  146. iconTransform.gameObject.SetActive(true);
  147. HorizontalLayoutGroup hgroup = iconTransform.parent.GetComponent<HorizontalLayoutGroup>();
  148. UnityEngine.Object.Destroy(hgroup);
  149. iconTransform.anchoredPosition = new Vector2(iconPos.x, iconPos.y);
  150. iconTransform.sizeDelta = new Vector2(iconSize.x, iconSize.y);
  151. iconTransform.localScale = new Vector2(iconScale.x, iconScale.y);
  152. iconTransform.Rotate(0, 0, iconRotation);
  153. UnityEngine.Object.Destroy(newButton.GetComponentsInChildren<RectTransform>(true).First(c => c.name == "Text").gameObject);
  154. UIBuilder.SetButtonBorder(ref newButton, Color.clear);
  155. UIBuilder.SetButtonIcon(ref newButton, iconSprite);
  156. return newButton;
  157. }
  158. /// <summary>
  159. /// Create a beat saber dismiss button.
  160. /// </summary>
  161. /// <param name="parent"></param>
  162. /// <returns></returns>
  163. public static Button CreateBackButton(RectTransform parent)
  164. {
  165. Button dismissButton = CreateUIButton(parent, "BackArrowButton");
  166. dismissButton.onClick.RemoveAllListeners();
  167. return dismissButton;
  168. }
  169. /// <summary>
  170. /// Generate TextMesh.
  171. /// </summary>
  172. /// <param name="parent"></param>
  173. /// <param name="text"></param>
  174. /// <param name="position"></param>
  175. /// <returns></returns>
  176. static public TextMeshProUGUI CreateText(RectTransform parent, string text, Vector2 position)
  177. {
  178. TextMeshProUGUI textMesh = new GameObject("TextMeshProUGUI_GO").AddComponent<TextMeshProUGUI>();
  179. textMesh.rectTransform.SetParent(parent, false);
  180. textMesh.text = text;
  181. textMesh.fontSize = 4;
  182. textMesh.color = Color.white;
  183. textMesh.font = Resources.Load<TMP_FontAsset>("Teko-Medium SDF No Glow");
  184. textMesh.rectTransform.anchorMin = new Vector2(0.5f, 1f);
  185. textMesh.rectTransform.anchorMax = new Vector2(0.5f, 1f);
  186. //textMesh.rectTransform.sizeDelta = size;
  187. textMesh.rectTransform.sizeDelta = new Vector2(60f, 10f);
  188. textMesh.rectTransform.anchoredPosition = position;
  189. return textMesh;
  190. }
  191. /// <summary>
  192. /// Adjust a Button text.
  193. /// </summary>
  194. /// <param name="button"></param>
  195. /// <param name="text"></param>
  196. static public void SetButtonText(ref Button button, string text)
  197. {
  198. if (button.GetComponentInChildren<TextMeshProUGUI>() != null)
  199. {
  200. button.GetComponentInChildren<TextMeshProUGUI>().text = text;
  201. }
  202. }
  203. /// <summary>
  204. /// Adjust button text size.
  205. /// </summary>
  206. /// <param name="button"></param>
  207. /// <param name="fontSize"></param>
  208. static public void SetButtonTextSize(ref Button button, float fontSize)
  209. {
  210. if (button.GetComponentInChildren<TextMeshProUGUI>() != null)
  211. {
  212. button.GetComponentInChildren<TextMeshProUGUI>().fontSize = fontSize;
  213. }
  214. }
  215. /// <summary>
  216. /// Set a button icon.
  217. /// </summary>
  218. /// <param name="button"></param>
  219. /// <param name="icon"></param>
  220. static public void SetButtonIcon(ref Button button, Sprite icon)
  221. {
  222. if (button.GetComponentsInChildren<UnityEngine.UI.Image>().Count() > 1)
  223. {
  224. button.GetComponentsInChildren<Image>().First(x => x.name == "Icon").sprite = icon;
  225. }
  226. }
  227. /// <summary>
  228. /// Disable a button icon.
  229. /// </summary>
  230. /// <param name="button"></param>
  231. /// <param name="enabled"></param>
  232. static public void SetButtonIconEnabled(ref Button button, bool enabled)
  233. {
  234. if (button.GetComponentsInChildren<UnityEngine.UI.Image>().Count() > 1)
  235. {
  236. button.GetComponentsInChildren<UnityEngine.UI.Image>()[1].enabled = enabled;
  237. }
  238. }
  239. /// <summary>
  240. /// Adjust button background color.
  241. /// </summary>
  242. /// <param name="button"></param>
  243. /// <param name="background"></param>
  244. static public void SetButtonBackground(ref Button button, Sprite background)
  245. {
  246. if (button.GetComponentsInChildren<Image>().Any())
  247. {
  248. button.GetComponentsInChildren<UnityEngine.UI.Image>()[0].sprite = background;
  249. }
  250. }
  251. /// <summary>
  252. /// Adjust button border.
  253. /// </summary>
  254. /// <param name="button"></param>
  255. /// <param name="color"></param>
  256. static public void SetButtonBorder(ref Button button, Color color)
  257. {
  258. if (button.GetComponentsInChildren<Image>().Any())
  259. {
  260. button.GetComponentsInChildren<UnityEngine.UI.Image>()[0].color = color;
  261. }
  262. }
  263. }
  264. }