public TableCell CellForIdx(int row) { LevelListTableCell cell = Instantiate(_songTableCellInstance); cell.reuseIdentifier = "SongCell"; cell.GetField <UnityEngine.UI.Image>("_coverImage").sprite = availableFiles[row].CoverImage; cell.GetField <TextMeshProUGUI>("_songNameText").text = availableFiles[row].FileName; cell.GetField <TextMeshProUGUI>("_authorText").text = ""; cell.SetField("_beatmapCharacteristicAlphas", new float[0]); cell.SetField("_beatmapCharacteristicImages", new UnityEngine.UI.Image[0]); cell.SetField("_bought", true); return(cell); }
public void Init(LevelListTableCell originalTableCell) { _backgroundImage = transform.Find("Background").GetComponent <ImageView>(); _nameText = transform.Find("SongName").GetComponent <CurvedTextMeshPro>(); _authorText = transform.Find("SongAuthor").GetComponent <CurvedTextMeshPro>(); _cover = transform.Find("CoverImage").GetComponent <ImageView>(); _nameText.richText = false; _authorText.richText = false; _nameText.name = "AvatarName"; _authorText.name = "AvatarAuthor"; _wasPressedSignal = originalTableCell.GetField <Signal, SelectableCell>("_wasPressedSignal"); }
//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// <summary> /// Get new table cell or reuse old one /// </summary> /// <returns></returns> private LevelListTableCell GetTableCell() { LevelListTableCell l_Cell = (LevelListTableCell)TableViewInstance.DequeueReusableCellForIdentifier("BSP_SongList_Cell"); if (!l_Cell) { if (m_SongListTableCellInstance == null) { m_SongListTableCellInstance = UnityEngine.Resources.FindObjectsOfTypeAll <LevelListTableCell>().First(x => (x.name == "LevelListTableCell")); } l_Cell = Instantiate(m_SongListTableCellInstance); } l_Cell.SetField("_notOwned", false); l_Cell.reuseIdentifier = "BSP_SongList_Cell"; if (m_DefaultCover == null) { m_DefaultCover = l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite; } return(l_Cell); }
private async void SetDataFromLevelAsync(SongRequest request, LevelListTableCell _tableCell, int row) { var favouritesBadge = _tableCell.GetField <Image, LevelListTableCell>("_favoritesBadgeImage"); favouritesBadge.enabled = false; var highlight = (request.requestInfo.Length > 0) && (request.requestInfo[0] == '!'); var msg = highlight ? "MSG" : ""; var hasMessage = (request.requestInfo.Length > 0) && (request.requestInfo[0] == '!'); var isChallenge = request.requestInfo.IndexOf("!challenge", StringComparison.OrdinalIgnoreCase) >= 0; var pp = ""; var ppvalue = request.song["pp"].AsInt; if (ppvalue > 0) { pp = $" {ppvalue} PP"; } var dt = new RequestBot.DynamicText().AddSong(request.song).AddUser(ref request.requestor); // Get basic fields dt.Add("Status", request.status.ToString()); dt.Add("Info", (request.requestInfo != "") ? " / " + request.requestInfo : ""); dt.Add("RequestTime", request.requestTime.ToLocalTime().ToString("hh:mm")); var songDurationText = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText"); songDurationText.text = request.song["songlength"].Value; var songBpm = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText"); (songBpm.transform as RectTransform).anchoredPosition = new Vector2(-2.5f, -1.8f); (songBpm.transform as RectTransform).sizeDelta += new Vector2(15f, 0f); var k = new List <string>(); if (hasMessage) { k.Add("MSG"); } if (isChallenge) { k.Add("VS"); } k.Add(request.song["id"]); songBpm.text = string.Join(" - ", k); var songBmpIcon = _tableCell.GetComponentsInChildren <Image>().LastOrDefault(c => string.Equals(c.name, "BpmIcon", StringComparison.OrdinalIgnoreCase)); if (songBmpIcon != null) { Destroy(songBmpIcon); } var songName = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_songNameText"); songName.richText = true; songName.text = $"{request.song["songName"].Value} <size=50%>{RequestBot.GetRating(ref request.song)} <color=#3fff3f>{pp}</color></size>"; var author = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_songAuthorText"); author.richText = true; author.text = dt.Parse(RequestBot.QueueListRow2); var image = _tableCell.GetField <Image, LevelListTableCell>("_coverImage"); var imageSet = false; if (SongCore.Loader.AreSongsLoaded) { var level = CustomLevelForRow(row); if (level != null) { // set image from song's cover image var sprite = await level.GetCoverImageAsync(System.Threading.CancellationToken.None); image.sprite = sprite; imageSet = true; } } if (!imageSet) { var url = request.song["coverURL"].Value; if (!_cachedTextures.TryGetValue(url, out var tex)) { var b = await Plugin.WebClient.DownloadImage($"{url}", System.Threading.CancellationToken.None); tex = new Texture2D(2, 2); tex.LoadImage(b); try { _cachedTextures.Add(url, tex); } catch (Exception) { // ignored } } image.sprite = Base64Sprites.Texture2DToSprite(tex); } UIHelper.AddHintText(_tableCell.transform as RectTransform, dt.Parse(RequestBot.SongHintText)); }
//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// <summary> /// Build cell /// </summary> /// <param name="p_TableView">Table view instance</param> /// <param name="p_Index">Cell index</param> /// <returns></returns> public HMUI.TableCell CellForIdx(HMUI.TableView p_TableView, int p_Index) { LevelListTableCell l_Cell = GetTableCell(); TextMeshProUGUI l_Text = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songNameText"); TextMeshProUGUI l_SubText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songAuthorText"); l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_favoritesBadgeImage").gameObject.SetActive(false); var l_HoverHint = l_Cell.gameObject.GetComponent <HMUI.HoverHint>(); if (l_HoverHint == null || !l_HoverHint) { l_HoverHint = l_Cell.gameObject.AddComponent <HMUI.HoverHint>(); l_HoverHint.SetField("_hoverHintController", UnityEngine.Resources.FindObjectsOfTypeAll <HMUI.HoverHintController>().First()); } if (l_Cell.gameObject.GetComponent <LocalizedHoverHint>()) { UnityEngine.GameObject.Destroy(l_Cell.gameObject.GetComponent <LocalizedHoverHint>()); } var l_SongEntry = Data[p_Index]; l_SongEntry.Init(); if ((l_SongEntry.BeatSaver_Map != null && !l_SongEntry.BeatSaver_Map.Partial) || l_SongEntry.CustomLevel != null) { var l_HaveSong = l_SongEntry.CustomLevel != null && SongCore.Loader.CustomLevels.ContainsKey(l_SongEntry.CustomLevel.customLevelPath); string l_MapName = ""; string l_MapAuthor = ""; string l_MapSongAuthor = ""; float l_Duration = 0f; float l_BPM = 0f; if (l_SongEntry.CustomLevel != null) { l_MapName = l_SongEntry.CustomLevel.songName; l_MapAuthor = l_SongEntry.CustomLevel.levelAuthorName; l_MapSongAuthor = l_SongEntry.CustomLevel.songAuthorName; l_BPM = l_SongEntry.CustomLevel.beatsPerMinute; l_Duration = l_SongEntry.CustomLevel.songDuration; } else { var l_FirstDiff = l_SongEntry.BeatSaver_Map.Metadata.Characteristics.First().Difficulties.Where(x => x.Value.HasValue).LastOrDefault(); l_MapName = l_SongEntry.BeatSaver_Map.Name; l_MapAuthor = l_SongEntry.BeatSaver_Map.Metadata.LevelAuthorName; l_MapSongAuthor = l_SongEntry.BeatSaver_Map.Metadata.SongAuthorName; l_BPM = l_SongEntry.BeatSaver_Map.Metadata.BPM; l_Duration = l_FirstDiff.Value.Value.Length; } string l_Title = l_SongEntry.TitlePrefix + (l_SongEntry.TitlePrefix.Length != 0 ? " " : "") + (l_HaveSong ? "<#7F7F7F>" : "") + l_MapName; string l_SubTitle = l_MapAuthor + " [" + l_MapSongAuthor + "]"; if (l_Title.Length > (28 + (l_HaveSong ? "<#7F7F7F>".Length : 0))) { l_Title = l_Title.Substring(0, 28 + (l_HaveSong ? "<#7F7F7F>".Length : 0)) + "..."; } if (l_SubTitle.Length > 28) { l_SubTitle = l_SubTitle.Substring(0, 28) + "..."; } l_Text.text = l_Title; l_SubText.text = l_SubTitle; var l_BPMText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText"); l_BPMText.gameObject.SetActive(true); l_BPMText.text = ((int)l_BPM).ToString(); var l_DurationText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText"); l_DurationText.gameObject.SetActive(true); l_DurationText.text = l_Duration >= 0.0 ? $"{Math.Floor((double)l_Duration / 60):N0}:{Math.Floor((double)l_Duration % 60):00}" : "--"; l_Cell.transform.Find("BpmIcon").gameObject.SetActive(true); if (l_SongEntry.Cover != null) { l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; } else if (CoverCache.TryGetValue(l_SongEntry.GetLevelHash(), out var l_Cover)) { l_SongEntry.Cover = l_Cover; l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; OnCoverFetched?.Invoke(l_Cell.idx, l_SongEntry); } else { l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = m_DefaultCover; if (l_HaveSong) { var l_CoverTask = l_SongEntry.CustomLevel.GetCoverImageAsync(CancellationToken.None); _ = l_CoverTask.ContinueWith(p_CoverTaskResult => { if (l_Cell.idx >= Data.Count || l_SongEntry != Data[l_Cell.idx]) { return; } Unity.MainThreadInvoker.Enqueue(() => { /// Update infos l_SongEntry.Cover = p_CoverTaskResult.Result; /// Cache cover if (!CoverCache.ContainsKey(l_SongEntry.GetLevelHash())) { CoverCache.Add(l_SongEntry.GetLevelHash(), l_SongEntry.Cover); } if (l_Cell.idx < Data.Count && l_SongEntry == Data[l_Cell.idx]) { l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; l_Cell.RefreshVisuals(); OnCoverFetched?.Invoke(l_Cell.idx, l_SongEntry); } }); }); } else if (l_SongEntry.BeatSaver_Map != null) { /// Fetch cover var l_CoverTask = l_SongEntry.BeatSaver_Map.FetchCoverImage(); _ = l_CoverTask.ContinueWith(p_CoverTaskResult => { if (l_Cell.idx >= Data.Count || l_SongEntry != Data[l_Cell.idx]) { return; } Unity.MainThreadInvoker.Enqueue(() => { var l_Texture = Unity.Texture2D.CreateFromRaw(p_CoverTaskResult.Result); if (l_Texture != null) { l_SongEntry.Cover = UnityEngine.Sprite.Create(l_Texture, new UnityEngine.Rect(0, 0, l_Texture.width, l_Texture.height), new UnityEngine.Vector2(0.5f, 0.5f), 100); /// Cache cover if (!CoverCache.ContainsKey(l_SongEntry.GetLevelHash())) { CoverCache.Add(l_SongEntry.GetLevelHash(), l_SongEntry.Cover); } if (l_Cell.idx < Data.Count && l_SongEntry == Data[l_Cell.idx]) { l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; l_Cell.RefreshVisuals(); OnCoverFetched?.Invoke(l_Cell.idx, l_SongEntry); } } }); }); } } } else if (l_SongEntry.BeatSaver_Map != null && l_SongEntry.BeatSaver_Map.Partial) { l_Text.text = "Loading from BeatSaver..."; l_SubText.text = ""; l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText").gameObject.SetActive(false); l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText").gameObject.SetActive(false); l_Cell.transform.Find("BpmIcon").gameObject.SetActive(false); l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = m_DefaultCover; } else { l_Text.text = "<#FF0000>Invalid song"; l_SubText.text = l_SongEntry.CustomLevel != null?l_SongEntry.CustomLevel.levelID.Replace("custom_level_", "") : ""; l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText").gameObject.SetActive(false); l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText").gameObject.SetActive(false); l_Cell.transform.Find("BpmIcon").gameObject.SetActive(false); l_Cell.GetField <UnityEngine.UI.Image, LevelListTableCell>("_coverImage").sprite = m_DefaultCover; } if (!string.IsNullOrEmpty(l_SongEntry.HoverHint)) { var l_HoverHintText = l_SongEntry.HoverHint; if (l_SongEntry.HoverHintTimeArg.HasValue && l_HoverHintText.Contains("$$time$$")) { var l_Replace = ""; var l_Elapsed = Misc.Time.UnixTimeNow() - Misc.Time.ToUnixTime(l_SongEntry.HoverHintTimeArg.Value); if (l_Elapsed < (60 * 60)) { l_Replace = Math.Max(1, l_Elapsed / 60).ToString() + " minute(s) ago"; } else if (l_Elapsed < (60 * 60 * 24)) { l_Replace = Math.Max(1, l_Elapsed / (60 * 60)).ToString() + " hour(s) ago"; } else { l_Replace = Math.Max(1, l_Elapsed / (60 * 60 * 24)).ToString() + " day(s) ago"; } l_HoverHintText = l_HoverHintText.Replace("$$time$$", l_Replace); } l_HoverHint.enabled = true; l_HoverHint.text = l_HoverHintText; } else { l_HoverHint.enabled = false; } return(l_Cell); }
//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// <summary> /// Build cell /// </summary> /// <param name="p_TableView">Table view instance</param> /// <param name="p_Index">Cell index</param> /// <returns></returns> public TableCell CellForIdx(TableView p_TableView, int p_Index) { LevelListTableCell l_Cell = GetTableCell(); TextMeshProUGUI l_Text = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songNameText"); TextMeshProUGUI l_SubText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songAuthorText"); l_Cell.GetField <Image, LevelListTableCell>("_favoritesBadgeImage").gameObject.SetActive(false); var l_HoverHint = l_Cell.gameObject.GetComponent <HoverHint>(); if (l_HoverHint == null || !l_HoverHint) { l_HoverHint = l_Cell.gameObject.AddComponent <HoverHint>(); l_HoverHint.SetField("_hoverHintController", Resources.FindObjectsOfTypeAll <HoverHintController>().First()); } if (l_Cell.gameObject.GetComponent <LocalizedHoverHint>()) { GameObject.Destroy(l_Cell.gameObject.GetComponent <LocalizedHoverHint>()); } var l_SongEntry = Data[p_Index]; if (!l_SongEntry.BeatMap.Partial) { var l_LocalSong = SongCore.Loader.GetLevelByHash(l_SongEntry.BeatMap.Hash); l_Text.text = l_SongEntry.NamePrefix + (l_SongEntry.NamePrefix.Length != 0 ? " " : "") + ((l_LocalSong != null && SongCore.Loader.CustomLevels.ContainsKey(l_LocalSong.customLevelPath)) ? "<#7F7F7F>" : "") + l_SongEntry.BeatMap.Name; l_SubText.text = l_SongEntry.BeatMap.Metadata.SongAuthorName + " [" + l_SongEntry.BeatMap.Metadata.LevelAuthorName + "]"; if (l_Text.text.Length > (28 + (l_LocalSong != null ? "<#7F7F7F>".Length : 0))) { l_Text.text = l_Text.text.Substring(0, 28 + (l_LocalSong != null ? "<#7F7F7F>".Length : 0)) + "..."; } if (l_SubText.text.Length > 28) { l_SubText.text = l_SubText.text.Substring(0, 28) + "..."; } var l_FirstDiff = l_SongEntry.BeatMap.Metadata.Characteristics.First().Difficulties.Where(x => x.Value.HasValue).LastOrDefault(); var l_BPMText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText"); l_BPMText.gameObject.SetActive(true); l_BPMText.text = ((int)l_SongEntry.BeatMap.Metadata.BPM).ToString(); var l_DurationText = l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText"); l_DurationText.gameObject.SetActive(true); l_DurationText.text = l_FirstDiff.Value.Value.Length >= 0.0 ? $"{Math.Floor((double)l_FirstDiff.Value.Value.Length / 60):N0}:{Math.Floor((double)l_FirstDiff.Value.Value.Length % 60):00}" : "--"; l_Cell.transform.Find("BpmIcon").gameObject.SetActive(true); if (l_SongEntry.Cover != null) { l_Cell.GetField <Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; } else { l_Cell.GetField <Image, LevelListTableCell>("_coverImage").sprite = m_DefaultCover; /// Fetch cover var l_CoverTask = l_SongEntry.BeatMap.FetchCoverImage(); _ = l_CoverTask.ContinueWith(p_CoverTaskResult => { if (l_Cell.idx >= Data.Count || l_SongEntry.BeatMap.Hash != Data[l_Cell.idx].BeatMap.Hash) { return; } HMMainThreadDispatcher.instance.Enqueue(() => { var l_Texture = new Texture2D(2, 2); if (l_Texture.LoadImage(p_CoverTaskResult.Result)) { l_SongEntry.Cover = Sprite.Create(l_Texture, new Rect(0, 0, l_Texture.width, l_Texture.height), new Vector2(0.5f, 0.5f), 100); if (l_Cell.idx < Data.Count && l_SongEntry.BeatMap.Hash == Data[l_Cell.idx].BeatMap.Hash) { l_Cell.GetField <Image, LevelListTableCell>("_coverImage").sprite = l_SongEntry.Cover; } } }); }); } } else { l_Text.text = "Loading from BeatSaver..."; l_SubText.text = ""; l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songBpmText").gameObject.SetActive(false); l_Cell.GetField <TextMeshProUGUI, LevelListTableCell>("_songDurationText").gameObject.SetActive(false); l_Cell.transform.Find("BpmIcon").gameObject.SetActive(false); l_Cell.GetField <Image, LevelListTableCell>("_coverImage").sprite = m_DefaultCover; } l_HoverHint.text = "Requested by <u>" + l_SongEntry.RequesterName + "</u>"; return(l_Cell); }
private async void SetDataFromLevelAsync(SongRequest request, LevelListTableCell _tableCell, int row) { var favouritesBadge = _tableCell.GetField <RawImage, LevelListTableCell>("_favoritesBadgeImage"); favouritesBadge.enabled = false; bool highlight = (request.requestInfo.Length > 0) && (request.requestInfo[0] == '!'); string msg = highlight ? "MSG" : ""; var hasMessage = (request.requestInfo.Length > 0) && (request.requestInfo[0] == '!'); var isChallenge = request.requestInfo.IndexOf("!challenge", StringComparison.OrdinalIgnoreCase) >= 0; var beatmapCharacteristicImages = _tableCell.GetField <UnityEngine.UI.Image[], LevelListTableCell>("_beatmapCharacteristicImages"); // NEW VERSION foreach (var i in beatmapCharacteristicImages) { i.enabled = false; } // causing a nullex? //_tableCell.SetField("_beatmapCharacteristicAlphas", new float[5] { 1f, 1f, 1f, 1f, 1f }); // set message icon if request has a message // NEW VERSION if (hasMessage) { beatmapCharacteristicImages.Last().sprite = Base64Sprites.InfoIcon; beatmapCharacteristicImages.Last().enabled = true; } // set challenge icon if song is a challenge if (isChallenge) { var el = beatmapCharacteristicImages.ElementAt(beatmapCharacteristicImages.Length - 2); el.sprite = Base64Sprites.VersusChallengeIcon; el.enabled = true; } string pp = ""; int ppvalue = request.song["pp"].AsInt; if (ppvalue > 0) { pp = $" {ppvalue} PP"; } var dt = new RequestBot.DynamicText().AddSong(request.song).AddUser(ref request.requestor); // Get basic fields dt.Add("Status", request.status.ToString()); dt.Add("Info", (request.requestInfo != "") ? " / " + request.requestInfo : ""); dt.Add("RequestTime", request.requestTime.ToLocalTime().ToString("hh:mm")); var songName = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_songNameText"); //songName.text = $"{request.song["songName"].Value} <size=50%>{RequestBot.GetRating(ref request.song)} <color=#3fff3f>{pp}</color></size> <color=#ff00ff>{msg}</color>"; songName.text = $"{request.song["songName"].Value} <size=50%>{RequestBot.GetRating(ref request.song)} <color=#3fff3f>{pp}</color></size>"; // NEW VERSION var author = _tableCell.GetField <TextMeshProUGUI, LevelListTableCell>("_authorText"); author.text = dt.Parse(RequestBot.QueueListRow2); var image = _tableCell.GetField <RawImage, LevelListTableCell>("_coverRawImage"); var imageSet = false; if (SongCore.Loader.AreSongsLoaded) { CustomPreviewBeatmapLevel level = CustomLevelForRow(row); if (level != null) { //Plugin.Log("custom level found"); // set image from song's cover image var tex = await level.GetCoverImageTexture2DAsync(System.Threading.CancellationToken.None); image.texture = tex; imageSet = true; } } if (!imageSet) { string url = request.song["coverURL"].Value; if (!_cachedTextures.TryGetValue(url, out var tex)) { var b = await Plugin.WebClient.DownloadImage($"https://beatsaver.com{url}", System.Threading.CancellationToken.None); tex = new Texture2D(2, 2); tex.LoadImage(b); try { _cachedTextures.Add(url, tex); } catch (Exception) { } } image.texture = tex; } UIHelper.AddHintText(_tableCell.transform as RectTransform, dt.Parse(RequestBot.SongHintText)); }