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.

332 lines
12 KiB

  1. using CustomUI.BeatSaber;
  2. using CustomUI.MenuButton;
  3. using IPA.Loader;
  4. using IPA.Updating.BeatMods;
  5. using IPA.Utilities;
  6. using System;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.Diagnostics;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using TMPro;
  14. using UnityEngine;
  15. using UnityEngine.UI;
  16. using VRUI;
  17. namespace BSIPA_ModList.UI
  18. {
  19. internal class ModInfoViewController : VRUIViewController
  20. {
  21. internal Sprite Icon;
  22. internal string Name;
  23. internal string Version;
  24. internal string Author;
  25. internal string Description;
  26. internal PluginLoader.PluginMetadata UpdateInfo;
  27. private static RectTransform rowTransformOriginal;
  28. private ModInfoView view;
  29. private RectTransform rowTransform;
  30. private Button linkHomeButton;
  31. private Button linkSourceButton;
  32. private Button linkDonateButton;
  33. public void Init(Sprite icon, string name, string version, string author, string description, PluginLoader.PluginMetadata updateInfo, PluginManifest.LinksObject links = null)
  34. {
  35. Icon = icon;
  36. Name = name;
  37. Version = version;
  38. Author = author;
  39. Description = description;
  40. UpdateInfo = updateInfo;
  41. if (rowTransformOriginal == null)
  42. rowTransformOriginal = MenuButtonUI.Instance.GetPrivateField<RectTransform>("menuButtonsOriginal");
  43. // i also have no clue why this is necessary
  44. rectTransform.anchorMin = new Vector2(0f, 0f);
  45. rectTransform.anchorMax = new Vector2(0.5f, 1f);
  46. var go = new GameObject("Info View", typeof(RectTransform));
  47. go.SetActive(false);
  48. go.AddComponent<RectMask2D>();
  49. view = go.AddComponent<ModInfoView>();
  50. var rt = view.transform as RectTransform;
  51. rt.SetParent(transform);
  52. rt.anchorMin = new Vector2(0f, 0f);
  53. rt.anchorMax = new Vector2(1f, 1f);
  54. rt.anchoredPosition = new Vector2(0f, 0);
  55. view.Init(this);
  56. go.SetActive(true);
  57. SetupLinks(links);
  58. }
  59. private void SetupLinks(PluginManifest.LinksObject links = null, Uri moreInfoLink = null)
  60. {
  61. bool addedLink = false;
  62. if (links != null || moreInfoLink != null)
  63. {
  64. Logger.log.Debug($"Adding links");
  65. rowTransform = Instantiate(rowTransformOriginal, rectTransform);
  66. rowTransform.anchorMin = new Vector2(0f, 0f);
  67. rowTransform.anchorMax = new Vector2(1f, .15f);
  68. rowTransform.anchoredPosition = new Vector2(-3.5f, -2f);
  69. foreach (Transform child in rowTransform)
  70. {
  71. child.name = string.Empty;
  72. Destroy(child.gameObject);
  73. }
  74. if (links?.ProjectHome != null)
  75. {
  76. linkHomeButton = BeatSaberUI.CreateUIButton(rowTransform, "QuitButton", buttonText: "Home",
  77. onClick: () => Process.Start(links.ProjectHome.ToString()));
  78. linkHomeButton.GetComponentInChildren<HorizontalLayoutGroup>().padding = new RectOffset(6, 6, 0, 0);
  79. addedLink = true;
  80. }
  81. if (links?.ProjectSource != null)
  82. {
  83. linkSourceButton = BeatSaberUI.CreateUIButton(rowTransform, "QuitButton", buttonText: "Source",
  84. onClick: () => Process.Start(links.ProjectSource.ToString()));
  85. linkSourceButton.GetComponentInChildren<HorizontalLayoutGroup>().padding = new RectOffset(6, 6, 0, 0);
  86. addedLink = true;
  87. }
  88. if (links?.Donate != null)
  89. {
  90. linkDonateButton = BeatSaberUI.CreateUIButton(rowTransform, "QuitButton", buttonText: "Donate",
  91. onClick: () => Process.Start(links.Donate.ToString()));
  92. linkDonateButton.GetComponentInChildren<HorizontalLayoutGroup>().padding = new RectOffset(6, 6, 0, 0);
  93. addedLink = true;
  94. }
  95. if (moreInfoLink != null)
  96. {
  97. linkDonateButton = BeatSaberUI.CreateUIButton(rowTransform, "QuitButton", buttonText: "More Info",
  98. onClick: () => Process.Start(moreInfoLink.ToString()));
  99. linkDonateButton.GetComponentInChildren<HorizontalLayoutGroup>().padding = new RectOffset(6, 6, 0, 0);
  100. addedLink = true;
  101. }
  102. }
  103. if (UpdateInfo != null && !addedLink)
  104. StartCoroutine(GetMoreInfoLink());
  105. }
  106. private IEnumerator GetMoreInfoLink()
  107. {
  108. Logger.log.Debug($"Getting more info link");
  109. Ref<ApiEndpoint.Mod> mod = new Ref<ApiEndpoint.Mod>(null);
  110. if (UpdateInfo.Id == null) yield break;
  111. yield return Updater.GetModInfo(UpdateInfo.Id, UpdateInfo.Version.ToString(), mod);
  112. try { mod.Verify(); }
  113. catch (Exception e)
  114. {
  115. Logger.log.Warn($"Error getting more info link for mod {UpdateInfo.Id}");
  116. Logger.log.Warn(e);
  117. yield break;
  118. }
  119. SetupLinks(null, mod.Value.Link);
  120. }
  121. #if DEBUG
  122. public void Update()
  123. {
  124. #if ADJUST_INFO_BUTTON_UI_LINKS
  125. RectTransform rt = rowTransform;
  126. if (rt == null) return;
  127. var cpos = rt.anchoredPosition;
  128. if (Input.GetKey(KeyCode.LeftArrow))
  129. {
  130. rt.anchoredPosition = new Vector2(cpos.x - .1f, cpos.y);
  131. }
  132. else if (Input.GetKey(KeyCode.RightArrow))
  133. {
  134. rt.anchoredPosition = new Vector2(cpos.x + .1f, cpos.y);
  135. }
  136. else if (Input.GetKey(KeyCode.UpArrow))
  137. {
  138. rt.anchoredPosition = new Vector2(cpos.x, cpos.y + .1f);
  139. }
  140. else if (Input.GetKey(KeyCode.DownArrow))
  141. {
  142. rt.anchoredPosition = new Vector2(cpos.x, cpos.y - .1f);
  143. }
  144. else
  145. return;
  146. Logger.log.Debug($"Position now at {rt.anchoredPosition}");
  147. #endif
  148. }
  149. #endif
  150. }
  151. internal class ModInfoView : MonoBehaviour
  152. {
  153. private TextMeshProUGUI titleText;
  154. private TextMeshProUGUI authorText;
  155. private TextMeshProUGUI descText;
  156. private Image icon;
  157. public void Init(ModInfoViewController controller)
  158. {
  159. var rectTransform = transform as RectTransform;
  160. rectTransform.sizeDelta = new Vector2(60f, 10f);
  161. titleText = BeatSaberUI.CreateText(rectTransform, $"{controller.Name} <size=60%>{controller.Version}", new Vector2(11f, 27.5f));
  162. titleText.fontSize = 6f;
  163. authorText = BeatSaberUI.CreateText(rectTransform, controller.Author, new Vector2(11f, 22f));
  164. authorText.fontSize = 4.5f;
  165. descText = BeatSaberUI.CreateText(rectTransform, controller.Description, new Vector2(-4.5f, 12f));
  166. descText.fontSize = 3.5f;
  167. descText.enableWordWrapping = true;
  168. descText.overflowMode = TextOverflowModes.ScrollRect;
  169. icon = new GameObject("Mod Info View Icon", typeof(RectTransform)).AddComponent<Image>();
  170. icon.gameObject.SetActive(false);
  171. icon.rectTransform.SetParent(rectTransform, false);
  172. icon.rectTransform.anchorMin = new Vector2(0.5f, 0.44f);
  173. icon.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
  174. icon.rectTransform.sizeDelta = new Vector2(60f, 10f);
  175. icon.rectTransform.anchoredPosition = new Vector2(-27.8f, 27.3f);
  176. icon.sprite = controller.Icon;
  177. icon.preserveAspect = true;
  178. icon.useSpriteMesh = true;
  179. icon.material = CustomUI.Utilities.UIUtilities.NoGlowMaterial;
  180. icon.gameObject.SetActive(true);
  181. }
  182. #if DEBUG
  183. #if ADJUST_INFO_TEXT_UI_KEYS
  184. private int currentItem = 0;
  185. #endif
  186. public void Update()
  187. {
  188. #if ADJUST_INFO_TEXT_UI_KEYS
  189. RectTransform rt;
  190. switch (currentItem)
  191. {
  192. default:
  193. currentItem = 0;
  194. goto case 0; // idk why this is needed tbh
  195. case 0:
  196. rt = titleText.rectTransform;
  197. break;
  198. case 1:
  199. rt = authorText.rectTransform;
  200. break;
  201. case 2:
  202. rt = descText.rectTransform;
  203. break;
  204. }
  205. if (Input.GetKeyDown(KeyCode.N))
  206. currentItem++;
  207. var cpos = rt.anchoredPosition;
  208. if (Input.GetKey(KeyCode.LeftArrow))
  209. {
  210. rt.anchoredPosition = new Vector2(cpos.x - .1f, cpos.y);
  211. }
  212. else if (Input.GetKey(KeyCode.RightArrow))
  213. {
  214. rt.anchoredPosition = new Vector2(cpos.x + .1f, cpos.y);
  215. }
  216. else if (Input.GetKey(KeyCode.UpArrow))
  217. {
  218. rt.anchoredPosition = new Vector2(cpos.x, cpos.y + .1f);
  219. }
  220. else if (Input.GetKey(KeyCode.DownArrow))
  221. {
  222. rt.anchoredPosition = new Vector2(cpos.x, cpos.y - .1f);
  223. }
  224. else
  225. return;
  226. Logger.log.Debug($"Position now at {rt.anchoredPosition}");
  227. #endif
  228. #if ADJUST_INFO_ICON_UI_KEYS
  229. var rt = icon.rectTransform;
  230. if (Input.GetKey(KeyCode.Z))
  231. { // adjust anchormin
  232. var cpos = rt.anchorMin;
  233. if (Input.GetKey(KeyCode.LeftArrow))
  234. {
  235. rt.anchorMin = new Vector2(cpos.x - .001f, cpos.y);
  236. }
  237. else if (Input.GetKey(KeyCode.RightArrow))
  238. {
  239. rt.anchorMin = new Vector2(cpos.x + .001f, cpos.y);
  240. }
  241. else if (Input.GetKey(KeyCode.UpArrow))
  242. {
  243. rt.anchorMin = new Vector2(cpos.x, cpos.y + .001f);
  244. }
  245. else if (Input.GetKey(KeyCode.DownArrow))
  246. {
  247. rt.anchorMin = new Vector2(cpos.x, cpos.y - .001f);
  248. }
  249. else
  250. return;
  251. Logger.log.Debug($"Anchor min now at {rt.anchorMin}");
  252. }
  253. else if(Input.GetKey(KeyCode.X))
  254. { // adjust anchorMax
  255. var cpos = rt.anchorMax;
  256. if (Input.GetKey(KeyCode.LeftArrow))
  257. {
  258. rt.anchorMax = new Vector2(cpos.x - .001f, cpos.y);
  259. }
  260. else if (Input.GetKey(KeyCode.RightArrow))
  261. {
  262. rt.anchorMax = new Vector2(cpos.x + .001f, cpos.y);
  263. }
  264. else if (Input.GetKey(KeyCode.UpArrow))
  265. {
  266. rt.anchorMax = new Vector2(cpos.x, cpos.y + .001f);
  267. }
  268. else if (Input.GetKey(KeyCode.DownArrow))
  269. {
  270. rt.anchorMax = new Vector2(cpos.x, cpos.y - .001f);
  271. }
  272. else
  273. return;
  274. Logger.log.Debug($"Anchor max now at {rt.anchorMax}");
  275. }
  276. else
  277. {
  278. var cpos = rt.anchoredPosition;
  279. if (Input.GetKey(KeyCode.LeftArrow))
  280. {
  281. rt.anchoredPosition = new Vector2(cpos.x - .1f, cpos.y);
  282. }
  283. else if (Input.GetKey(KeyCode.RightArrow))
  284. {
  285. rt.anchoredPosition = new Vector2(cpos.x + .1f, cpos.y);
  286. }
  287. else if (Input.GetKey(KeyCode.UpArrow))
  288. {
  289. rt.anchoredPosition = new Vector2(cpos.x, cpos.y + .1f);
  290. }
  291. else if (Input.GetKey(KeyCode.DownArrow))
  292. {
  293. rt.anchoredPosition = new Vector2(cpos.x, cpos.y - .1f);
  294. }
  295. else
  296. return;
  297. Logger.log.Debug($"Position now at {rt.anchoredPosition}");
  298. }
  299. #endif
  300. }
  301. #endif
  302. }
  303. }