From 82a847b820e11adb2bbbfccd4c0778d3e9ca9638 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Apr 2018 15:16:10 +0900 Subject: [PATCH] Extract random selection logic into CarouselRoot --- osu.Game/Screens/Select/BeatmapCarousel.cs | 6 ++--- .../Carousel/CarouselGroupEagerSelect.cs | 27 +++++++++---------- .../Screens/Select/Carousel/CarouselRoot.cs | 23 ++++++++++++++++ 3 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 osu.Game/Screens/Select/Carousel/CarouselRoot.cs diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 12791eb193..dfbbc2b5d5 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Select get { return beatmapSets.Select(g => g.BeatmapSet); } set { - CarouselGroup newRoot = new CarouselGroupEagerSelect(this); + CarouselRoot newRoot = new CarouselRoot(this); Task.Run(() => { @@ -102,11 +102,11 @@ namespace osu.Game.Screens.Select private readonly Stack randomSelectedBeatmaps = new Stack(); protected List Items = new List(); - private CarouselGroup root; + private CarouselRoot root; public BeatmapCarousel() { - root = new CarouselGroupEagerSelect(this); + root = new CarouselRoot(this); Child = new OsuContextMenuContainer { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 7f64af8216..fabf333461 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -11,11 +11,8 @@ namespace osu.Game.Screens.Select.Carousel /// public class CarouselGroupEagerSelect : CarouselGroup { - private readonly BeatmapCarousel parent; - - public CarouselGroupEagerSelect(BeatmapCarousel parent = null) + public CarouselGroupEagerSelect() { - this.parent = parent; State.ValueChanged += v => { if (v == CarouselItemState.Selected) @@ -23,13 +20,16 @@ namespace osu.Game.Screens.Select.Carousel }; } + /// + /// The last selected item. + /// + protected CarouselItem LastSelected { get; private set; } + /// /// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location. /// private int lastSelectedIndex; - private CarouselItem lastSelected; - /// /// To avoid overhead during filter operations, we don't attempt any selections until after all /// children have been filtered. This bool will be true during the base @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Select.Carousel { base.RemoveChild(i); - if (i != lastSelected) + if (i != LastSelected) updateSelectedIndex(); } @@ -86,12 +86,11 @@ namespace osu.Game.Screens.Select.Carousel // we only perform eager selection if none of our children are in a selected state already. if (Children.Any(i => i.State == CarouselItemState.Selected)) return; - if (parent != null && lastSelected == null) - { - parent.SelectNextRandom(); - return; - } + PerformSelection(); + } + protected virtual void PerformSelection() + { CarouselItem nextToSelect = Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered) ?? Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered); @@ -104,10 +103,10 @@ namespace osu.Game.Screens.Select.Carousel private void updateSelected(CarouselItem newSelection) { - lastSelected = newSelection; + LastSelected = newSelection; updateSelectedIndex(); } - private void updateSelectedIndex() => lastSelectedIndex = lastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(lastSelected)); + private void updateSelectedIndex() => lastSelectedIndex = LastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(LastSelected)); } } diff --git a/osu.Game/Screens/Select/Carousel/CarouselRoot.cs b/osu.Game/Screens/Select/Carousel/CarouselRoot.cs new file mode 100644 index 0000000000..b23d7631c9 --- /dev/null +++ b/osu.Game/Screens/Select/Carousel/CarouselRoot.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Select.Carousel +{ + public class CarouselRoot : CarouselGroupEagerSelect + { + private readonly BeatmapCarousel carousel; + + public CarouselRoot(BeatmapCarousel carousel) + { + this.carousel = carousel; + } + + protected override void PerformSelection() + { + if (LastSelected == null) + carousel.SelectNextRandom(); + else + base.PerformSelection(); + } + } +}