private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet) { if (beatmapSet.Beatmaps.All(b => b.Hidden)) { return(null); } // todo: remove the need for this. foreach (var b in beatmapSet.Beatmaps) { if (b.Metadata == null) { b.Metadata = beatmapSet.Metadata; } } var set = new CarouselBeatmapSet(beatmapSet); foreach (var c in set.Beatmaps) { c.State.ValueChanged += v => { if (v == CarouselItemState.Selected) { selectedBeatmapSet = set; SelectionChanged?.Invoke(c.Beatmap); itemsCache.Invalidate(); scrollPositionCache.Invalidate(); } }; } return(set); }
public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) { Schedule(() => { CarouselBeatmapSet existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID); bool hadSelection = existingSet?.State?.Value == CarouselItemState.Selected; var newSet = createCarouselSet(beatmapSet); if (existingSet != null) { root.RemoveChild(existingSet); } if (newSet == null) { itemsCache.Invalidate(); return; } root.AddChild(newSet); applyActiveCriteria(false, false); //check if we can/need to maintain our current selection. if (hadSelection) { select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet); } itemsCache.Invalidate(); Schedule(() => BeatmapSetsChanged?.Invoke()); }); }
public override void RemoveChild(CarouselItem i) { CarouselBeatmapSet set = (CarouselBeatmapSet)i; BeatmapSetsByID.Remove(set.BeatmapSet.ID); base.RemoveChild(i); }
public override void AddChild(CarouselItem i) { CarouselBeatmapSet set = (CarouselBeatmapSet)i; BeatmapSetsByID.Add(set.BeatmapSet.ID, set); base.AddChild(i); }
/// <summary> /// Computes the target Y positions for every item in the carousel. /// </summary> /// <returns>The Y position of the currently selected item.</returns> private void updateItems() { Items = root.Drawables.ToList(); yPositions.Clear(); float currentY = DrawHeight / 2; DrawableCarouselBeatmapSet lastSet = null; scrollTarget = null; foreach (DrawableCarouselItem d in Items) { if (d.IsPresent) { switch (d) { case DrawableCarouselBeatmapSet set: lastSet = set; set.MoveToX(set.Item.State == CarouselItemState.Selected ? -100 : 0, 500, Easing.OutExpo); set.MoveToY(currentY, 750, Easing.OutExpo); break; case DrawableCarouselBeatmap beatmap: if (beatmap.Item.State.Value == CarouselItemState.Selected) { scrollTarget = currentY + beatmap.DrawHeight / 2 - DrawHeight / 2; } void performMove(float y, float?startY = null) { if (startY != null) { beatmap.MoveTo(new Vector2(0, startY.Value)); } beatmap.MoveToX(beatmap.Item.State == CarouselItemState.Selected ? -50 : 0, 500, Easing.OutExpo); beatmap.MoveToY(y, 750, Easing.OutExpo); } Debug.Assert(lastSet != null); float?setY = null; if (!d.IsLoaded || beatmap.Alpha == 0) // can't use IsPresent due to DrawableCarouselItem override. // ReSharper disable once PossibleNullReferenceException (resharper broken?) { setY = lastSet.Y + lastSet.DrawHeight + 5; } if (d.IsLoaded) { performMove(currentY, setY); } else { float y = currentY; d.OnLoadComplete = _ => performMove(y, setY); } break; } } yPositions.Add(currentY); if (d.Item.Visible) { currentY += d.DrawHeight + 5; } } currentY += DrawHeight / 2; scrollableContent.Height = currentY; if (initialLoadComplete && (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); } itemsCache.Validate(); }