diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs index 274eeb9440..6cc2d62402 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs @@ -1,9 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using osu.Desktop.VisualTests.Platform; using osu.Framework.Screens.Testing; +using osu.Framework.MathUtils; using osu.Game.Database; using osu.Game.Modes; using osu.Game.Screens.Select; @@ -14,6 +16,7 @@ namespace osu.Desktop.VisualTests.Tests { private BeatmapDatabase db, oldDb; private TestStorage storage; + private PlaySongSelect songSelect; public override string Name => @"Song Select"; public override string Description => @"with fake data"; @@ -35,9 +38,15 @@ namespace osu.Desktop.VisualTests.Tests db.Import(sets); } - Add(new PlaySongSelect()); + + Add(songSelect = new PlaySongSelect()); + + AddButton(@"Sort by Artist", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Artist; }); + AddButton(@"Sort by Title", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Title; }); + AddButton(@"Sort by Author", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Author; }); + AddButton(@"Sort by Difficulty", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Difficulty; }); } - + protected override void Dispose(bool isDisposing) { if (oldDb != null) @@ -59,9 +68,10 @@ namespace osu.Desktop.VisualTests.Tests Metadata = new BeatmapMetadata { OnlineBeatmapSetID = 1234 + i, - Artist = "MONACA", - Title = "Black Song", - Author = "Some Guy", + // Create random metadata, then we can check if sorting works based on these + Artist = "MONACA " + RNG.Next(0, 9), + Title = "Black Song " + RNG.Next(0, 9), + Author = "Some Guy " + RNG.Next(0, 9), }, Beatmaps = new List(new[] { diff --git a/osu.Game.Modes.Osu/Objects/HitCircle.cs b/osu.Game.Modes.Osu/Objects/HitCircle.cs index 80f9317d96..2d86f0225f 100644 --- a/osu.Game.Modes.Osu/Objects/HitCircle.cs +++ b/osu.Game.Modes.Osu/Objects/HitCircle.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes.Osu.Objects { public class HitCircle : OsuHitObject diff --git a/osu.Game.Modes.Osu/Objects/SliderTick.cs b/osu.Game.Modes.Osu/Objects/SliderTick.cs index d9b8c03c3c..4492af86f9 100644 --- a/osu.Game.Modes.Osu/Objects/SliderTick.cs +++ b/osu.Game.Modes.Osu/Objects/SliderTick.cs @@ -1,4 +1,7 @@ -namespace osu.Game.Modes.Osu.Objects +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Modes.Osu.Objects { public class SliderTick : OsuHitObject { diff --git a/osu.Game.Modes.Osu/Objects/Spinner.cs b/osu.Game.Modes.Osu/Objects/Spinner.cs index 8a9b5bbbe3..d55b9eb59c 100644 --- a/osu.Game.Modes.Osu/Objects/Spinner.cs +++ b/osu.Game.Modes.Osu/Objects/Spinner.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes.Osu.Objects { public class Spinner : OsuHitObject diff --git a/osu.Game.Modes.Osu/OsuScore.cs b/osu.Game.Modes.Osu/OsuScore.cs index ce651e0809..6ea8eff890 100644 --- a/osu.Game.Modes.Osu/OsuScore.cs +++ b/osu.Game.Modes.Osu/OsuScore.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes.Osu { class OsuScore : Score diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 7a976a1f7a..1c2ae2bf78 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -88,7 +88,7 @@ namespace osu.Game.Database return ID == other?.ID; } - public bool AudioEquals(BeatmapInfo other) => other != null && + public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && BeatmapSet.Path == other.BeatmapSet.Path && (Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; } diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index f657ffe330..2f53d00c7e 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -1,4 +1,7 @@ -using OpenTK.Graphics; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; using OpenTK.Input; using osu.Framework.Input; using System; diff --git a/osu.Game/Modes/Objects/HitObjectParser.cs b/osu.Game/Modes/Objects/HitObjectParser.cs index 4020c1c069..5aa9f08589 100644 --- a/osu.Game/Modes/Objects/HitObjectParser.cs +++ b/osu.Game/Modes/Objects/HitObjectParser.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes.Objects { public abstract class HitObjectParser diff --git a/osu.Game/Modes/Objects/NullHitObjectParser.cs b/osu.Game/Modes/Objects/NullHitObjectParser.cs index 4f06d5ab26..fdec989632 100644 --- a/osu.Game/Modes/Objects/NullHitObjectParser.cs +++ b/osu.Game/Modes/Objects/NullHitObjectParser.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes.Objects { /// diff --git a/osu.Game/Modes/Score.cs b/osu.Game/Modes/Score.cs index df1b65872f..8da09cb974 100644 --- a/osu.Game/Modes/Score.cs +++ b/osu.Game/Modes/Score.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Modes { public class Score diff --git a/osu.Game/Modes/UI/HealthDisplay.cs b/osu.Game/Modes/UI/HealthDisplay.cs index 5201a58104..c8d45bac36 100644 --- a/osu.Game/Modes/UI/HealthDisplay.cs +++ b/osu.Game/Modes/UI/HealthDisplay.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using osu.Framework.Allocation; diff --git a/osu.Game/Online/API/IOnlineComponent.cs b/osu.Game/Online/API/IOnlineComponent.cs index a4d25613b8..d213f5a0fc 100644 --- a/osu.Game/Online/API/IOnlineComponent.cs +++ b/osu.Game/Online/API/IOnlineComponent.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Online.API { public interface IOnlineComponent diff --git a/osu.Game/Screens/Select/CarouselContainer.cs b/osu.Game/Screens/Select/CarouselContainer.cs index 9d8f489755..bb391c2eb7 100644 --- a/osu.Game/Screens/Select/CarouselContainer.cs +++ b/osu.Game/Screens/Select/CarouselContainer.cs @@ -183,6 +183,7 @@ namespace osu.Game.Screens.Select if (SelectedGroup != null && SelectedGroup != group && SelectedGroup.State != BeatmapGroupState.Hidden) SelectedGroup.State = BeatmapGroupState.Collapsed; + group.State = BeatmapGroupState.Expanded; SelectedGroup = group; panel.State = PanelSelectedState.Selected; SelectedPanel = panel; @@ -191,6 +192,58 @@ namespace osu.Game.Screens.Select ScrollTo(selectedY, animated); } + public void Sort(FilterControl.SortMode mode) { + switch (mode) { + case FilterControl.SortMode.Artist: + groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Artist, y.BeatmapSet.Metadata.Artist)); + break; + case FilterControl.SortMode.Title: + groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Title, y.BeatmapSet.Metadata.Title)); + break; + case FilterControl.SortMode.Author: + groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Author, y.BeatmapSet.Metadata.Author)); + break; + case FilterControl.SortMode.Difficulty: + groups.Sort((x, y) => + { + float xAverage=0, yAverage=0; + int counter=0; + foreach (BeatmapInfo set in x.BeatmapSet.Beatmaps) { + xAverage += set.StarDifficulty; + counter++; + } + xAverage /= counter; + counter = 0; + foreach (BeatmapInfo set in y.BeatmapSet.Beatmaps) { + yAverage += set.StarDifficulty; + counter++; + } + yAverage /= counter; + if (xAverage > yAverage) + return 1; + else + return -1; + }); + break; + default: + throw new NotImplementedException(); + } + scrollableContent.Clear(false); + lifetime.Clear(); + foreach (BeatmapGroup group in groups) + { + group.Header.Depth = -scrollableContent.Children.Count(); + scrollableContent.Add(group.Header); + + foreach (BeatmapPanel panel in group.BeatmapPanels) + { + panel.Depth = -scrollableContent.Children.Count(); + scrollableContent.Add(panel); + } + } + SelectGroup(groups.FirstOrDefault(), groups.First().BeatmapPanels.FirstOrDefault()); + } + private static float offsetX(float dist, float halfHeight) { // The radius of the circle the carousel moves on. diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 357346bc65..fd7992ba16 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -21,7 +21,18 @@ namespace osu.Game.Screens.Select public Action FilterChanged; public string Search => searchTextBox.Text; - public SortMode Sort { get; private set; } = SortMode.Title; + private SortMode sort = SortMode.Title; + public SortMode Sort { + get { return sort; } + set { + if (sort != value) + { + sort = value; + FilterChanged?.Invoke(); + } + } + } + public Action Exit; private SearchTextBox searchTextBox; @@ -251,9 +262,9 @@ namespace osu.Game.Screens.Select public enum SortMode { - Arist, + Artist, BPM, - Creator, + Author, DateAdded, Difficulty, Length, @@ -264,9 +275,9 @@ namespace osu.Game.Screens.Select public enum GroupMode { NoGrouping, - Arist, + Artist, BPM, - Creator, + Author, DateAdded, Difficulty, Length, diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 06dc321f3b..4252de2978 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -56,7 +56,22 @@ namespace osu.Game.Screens.Select OsuScreen player; - FilterControl filter; + private FilterControl filter; + public FilterControl Filter + { + get + { + return filter; + } + private set + { + if (filter != value) + { + filter = value; + filterChanged(); + } + } + } [BackgroundDependencyLoader(permitNulls: true)] private void load(BeatmapDatabase beatmaps, AudioManager audio, DialogOverlay dialog, Framework.Game game, @@ -164,6 +179,7 @@ namespace osu.Game.Screens.Select filterTask = null; var search = filter.Search; BeatmapGroup newSelection = null; + carousel.Sort(filter.Sort); foreach (var beatmapGroup in carousel) { var set = beatmapGroup.BeatmapSet; @@ -375,6 +391,7 @@ namespace osu.Game.Screens.Select if (token.IsCancellationRequested) return; addBeatmapSet(beatmapSet, game); } + filterChanged(); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 5928d6106c..540bfdbbf9 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Users { public class User