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.

347 lines
13 KiB

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