diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index e5f3d93a7d..c090ea6f0a 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Select public override bool HandleInput => AllowSelection; - private IEnumerable beatmapSets => root.Children?.OfType() ?? new CarouselBeatmapSet[] { }; + private IEnumerable beatmapSets => root.Children.OfType(); public IEnumerable BeatmapSets { @@ -277,7 +277,7 @@ namespace osu.Game.Screens.Select private void applyActiveCriteria(bool debounce, bool scroll) { - if (root.Children?.Any() != true) return; + if (root.Children.Any() != true) return; void perform() { diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs index b8d7ddaf3e..a54eeb562e 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs @@ -14,15 +14,63 @@ namespace osu.Game.Screens.Select.Carousel protected override DrawableCarouselItem CreateDrawableRepresentation() => null; - public override void AddChild(CarouselItem i) + public IReadOnlyList Children => InternalChildren; + + protected List InternalChildren = new List(); + + public override List Drawables + { + get + { + var drawables = base.Drawables; + foreach (var c in InternalChildren) + drawables.AddRange(c.Drawables); + return drawables; + } + } + + public virtual void RemoveChild(CarouselItem i) + { + InternalChildren.Remove(i); + + // it's important we do the deselection after removing, so any further actions based on + // State.ValueChanged make decisions post-removal. + i.State.Value = CarouselItemState.Collapsed; + } + + public virtual void AddChild(CarouselItem i) { i.State.ValueChanged += v => ChildItemStateChanged(i, v); - base.AddChild(i); + InternalChildren.Add(i); } public CarouselGroup(List items = null) { if (items != null) InternalChildren = items; + + State.ValueChanged += v => + { + switch (v) + { + case CarouselItemState.Collapsed: + case CarouselItemState.NotSelected: + InternalChildren.ForEach(c => c.State.Value = CarouselItemState.Collapsed); + break; + case CarouselItemState.Selected: + InternalChildren.ForEach(c => + { + if (c.State == CarouselItemState.Collapsed) c.State.Value = CarouselItemState.NotSelected; + }); + break; + } + }; + } + + public override void Filter(FilterCriteria criteria) + { + base.Filter(criteria); + InternalChildren.Sort((x, y) => x.CompareTo(criteria, y)); + InternalChildren.ForEach(c => c.Filter(criteria)); } protected virtual void ChildItemStateChanged(CarouselItem item, CarouselItemState value) diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 586e959a74..7d76aee253 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -13,66 +13,28 @@ namespace osu.Game.Screens.Select.Carousel public readonly Bindable State = new Bindable(CarouselItemState.NotSelected); - public IReadOnlyList Children => InternalChildren; - - protected List InternalChildren { get; set; } - /// /// This item is not in a hidden state. /// public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered; - public IEnumerable Drawables + public virtual List Drawables { get { - List items = new List(); + var items = new List(); var self = drawableRepresentation.Value; if (self?.IsPresent == true) items.Add(self); - if (InternalChildren != null) - foreach (var c in InternalChildren) - items.AddRange(c.Drawables); - return items; } } - public virtual void AddChild(CarouselItem i) => (InternalChildren ?? (InternalChildren = new List())).Add(i); - - public virtual void RemoveChild(CarouselItem i) - { - InternalChildren?.Remove(i); - - // it's important we do the deselection after removing, so any further actions based on - // State.ValueChanged make decisions post-removal. - i.State.Value = CarouselItemState.Collapsed; - } - protected CarouselItem() { drawableRepresentation = new Lazy(CreateDrawableRepresentation); - State.ValueChanged += v => - { - if (InternalChildren == null) return; - - switch (v) - { - case CarouselItemState.Collapsed: - case CarouselItemState.NotSelected: - InternalChildren.ForEach(c => c.State.Value = CarouselItemState.Collapsed); - break; - case CarouselItemState.Selected: - InternalChildren.ForEach(c => - { - if (c.State == CarouselItemState.Collapsed) c.State.Value = CarouselItemState.NotSelected; - }); - break; - } - }; - Filtered.ValueChanged += v => { if (v && State == CarouselItemState.Selected) @@ -86,8 +48,6 @@ namespace osu.Game.Screens.Select.Carousel public virtual void Filter(FilterCriteria criteria) { - InternalChildren?.Sort((x, y) => x.CompareTo(criteria, y)); - InternalChildren?.ForEach(c => c.Filter(criteria)); } public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => GetHashCode().CompareTo(other.GetHashCode());