diff --git a/osu-framework b/osu-framework index 6f7528255c..46a56e0e11 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6f7528255c5d6cde72f1e92de539983bc4bce502 +Subproject commit 46a56e0e11d56c788ff8db089582718a606ed158 diff --git a/osu.Desktop.VisualTests/Tests/TestCaseDirect.cs b/osu.Desktop.VisualTests/Tests/TestCaseDirect.cs index 6b68ffa260..2a20bca836 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseDirect.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseDirect.cs @@ -48,6 +48,17 @@ namespace osu.Desktop.VisualTests.Tests Author = @"RLC", Source = @"", }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Card = @"https://assets.ppy.sh/beatmaps/578332/covers/card.jpg?1494591390", + Cover = @"https://assets.ppy.sh/beatmaps/578332/covers/cover.jpg?1494591390", + }, + Preview = @"https://b.ppy.sh/preview/578332.mp3", + PlayCount = 97, + FavouriteCount = 72, + }, Beatmaps = new List { new BeatmapInfo @@ -55,13 +66,6 @@ namespace osu.Desktop.VisualTests.Tests Ruleset = ruleset, StarDifficulty = 5.35f, Metadata = new BeatmapMetadata(), - OnlineInfo = new BeatmapOnlineInfo - { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/578332/covers/cover.jpg?1494591390" }, - Preview = @"https://b.ppy.sh/preview/578332.mp3", - PlayCount = 97, - FavouriteCount = 72, - }, }, }, }, @@ -74,6 +78,17 @@ namespace osu.Desktop.VisualTests.Tests Author = @"Sotarks", Source = @"ぎんぎつね", }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Card = @"https://assets.ppy.sh/beatmaps/599627/covers/card.jpg?1494539318", + Cover = @"https://assets.ppy.sh/beatmaps/599627/covers/cover.jpg?1494539318", + }, + Preview = @"https//b.ppy.sh/preview/599627.mp3", + PlayCount = 3082, + FavouriteCount = 14, + }, Beatmaps = new List { new BeatmapInfo @@ -81,13 +96,6 @@ namespace osu.Desktop.VisualTests.Tests Ruleset = ruleset, StarDifficulty = 5.81f, Metadata = new BeatmapMetadata(), - OnlineInfo = new BeatmapOnlineInfo - { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/599627/covers/cover.jpg?1494539318" }, - Preview = @"https//b.ppy.sh/preview/599627.mp3", - PlayCount = 3082, - FavouriteCount = 14, - }, }, }, }, @@ -100,6 +108,17 @@ namespace osu.Desktop.VisualTests.Tests Author = @"Cerulean Veyron", Source = @"", }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Card = @"https://assets.ppy.sh/beatmaps/513268/covers/card.jpg?1494502863", + Cover = @"https://assets.ppy.sh/beatmaps/513268/covers/cover.jpg?1494502863", + }, + Preview = @"https//b.ppy.sh/preview/513268.mp3", + PlayCount = 2762, + FavouriteCount = 15, + }, Beatmaps = new List { new BeatmapInfo @@ -107,13 +126,6 @@ namespace osu.Desktop.VisualTests.Tests Ruleset = ruleset, StarDifficulty = 0.9f, Metadata = new BeatmapMetadata(), - OnlineInfo = new BeatmapOnlineInfo - { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/513268/covers/cover.jpg?1494502863" }, - Preview = @"https//b.ppy.sh/preview/513268.mp3", - PlayCount = 2762, - FavouriteCount = 15, - }, }, new BeatmapInfo { @@ -141,6 +153,17 @@ namespace osu.Desktop.VisualTests.Tests Author = @"[Kamiya]", Source = @"小林さんちのメイドラゴン", }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Card = @"https://assets.ppy.sh/beatmaps/586841/covers/card.jpg?1494052741", + Cover = @"https://assets.ppy.sh/beatmaps/586841/covers/cover.jpg?1494052741", + }, + Preview = @"https//b.ppy.sh/preview/586841.mp3", + PlayCount = 62317, + FavouriteCount = 161, + }, Beatmaps = new List { new BeatmapInfo @@ -148,13 +171,6 @@ namespace osu.Desktop.VisualTests.Tests Ruleset = ruleset, StarDifficulty = 1.26f, Metadata = new BeatmapMetadata(), - OnlineInfo = new BeatmapOnlineInfo - { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/586841/covers/cover.jpg?1494052741" }, - Preview = @"https//b.ppy.sh/preview/586841.mp3", - PlayCount = 62317, - FavouriteCount = 161, - }, }, new BeatmapInfo { diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs index 00d7e8b5c8..0c5f21a185 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs @@ -76,7 +76,7 @@ namespace osu.Desktop.VisualTests.Tests ControlPointInfo = controlPointInfo }); - Add(new Drawable[] + AddRange(new Drawable[] { new Container { diff --git a/osu.Desktop.VisualTests/Tests/TestCaseRoomInspector.cs b/osu.Desktop.VisualTests/Tests/TestCaseRoomInspector.cs index 00702f7ad0..4d650afed5 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseRoomInspector.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseRoomInspector.cs @@ -39,9 +39,15 @@ namespace osu.Desktop.VisualTests.Tests Artist = @"Maaya Sakamoto", Author = @"uwutm8", }, - OnlineInfo = new BeatmapOnlineInfo + BeatmapSet = new BeatmapSetInfo { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/560573/covers/cover.jpg?1492722343" }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/560573/covers/cover.jpg?1492722343", + }, + }, }, } }, @@ -96,15 +102,21 @@ namespace osu.Desktop.VisualTests.Tests Ruleset = rulesets.GetRuleset(0), Metadata = new BeatmapMetadata { - Title = @"xi", - Artist = @"FREEDOM DIVE", + Title = @"FREEDOM DIVE", + Artist = @"xi", Author = @"Nakagawa-Kanon", }, - OnlineInfo = new BeatmapOnlineInfo + BeatmapSet = new BeatmapSetInfo { - Covers = new[] { @"https://assets.ppy.sh//beatmaps/39804/covers/cover.jpg?1456506845" }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/39804/covers/cover.jpg?1456506845", + }, + }, }, - } + }, }, MaxParticipants = { Value = 10 }, Participants = diff --git a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs index e8fc2956b4..fc29e8481e 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs @@ -50,7 +50,7 @@ namespace osu.Desktop.VisualTests.Tests Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Position = new Vector2(20, -160), - Count = 5, + CountStars = 5, }; Add(stars); @@ -59,7 +59,7 @@ namespace osu.Desktop.VisualTests.Tests Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Position = new Vector2(20, -190), - Text = stars.Count.ToString("0.00"), + Text = stars.CountStars.ToString("0.00"), }; Add(starsLabel); @@ -69,8 +69,8 @@ namespace osu.Desktop.VisualTests.Tests comboCounter.Current.Value = 0; numerator = denominator = 0; accuracyCounter.SetFraction(0, 0); - stars.Count = 0; - starsLabel.Text = stars.Count.ToString("0.00"); + stars.CountStars = 0; + starsLabel.Text = stars.CountStars.ToString("0.00"); }); AddStep(@"Hit! :D", delegate @@ -91,8 +91,8 @@ namespace osu.Desktop.VisualTests.Tests AddStep(@"Alter stars", delegate { - stars.Count = RNG.NextSingle() * (stars.StarCount + 1); - starsLabel.Text = stars.Count.ToString("0.00"); + stars.CountStars = RNG.NextSingle() * (stars.StarCount + 1); + starsLabel.Text = stars.CountStars.ToString("0.00"); }); AddStep(@"Stop counters", delegate diff --git a/osu.Desktop.VisualTests/Tests/TestCaseScrollingHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseScrollingHitObjects.cs index 9f439fe193..8e5cf8687c 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseScrollingHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseScrollingHitObjects.cs @@ -55,7 +55,7 @@ namespace osu.Desktop.VisualTests.Tests timeRangeBindable.ValueChanged += v => timeRangeText.Text = $"Visible Range: {v:#,#.#}"; timeRangeBindable.ValueChanged += v => bottomLabel.Text = $"t minus {v:#,#}"; - Add(new Drawable[] + AddRange(new Drawable[] { new Container { diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 9182f925e1..0a10a60dca 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -202,7 +202,7 @@ namespace osu.Desktop.Overlays { this.game = game; - IconContent.Add(new Drawable[] + IconContent.AddRange(new Drawable[] { new Box { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e52fb1362f..17b0b0a607 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; - Add(new Drawable[] + AddRange(new Drawable[] { // For now the body piece covers the entire height of the container // whereas possibly in the future we don't want to extend under the head/tail. diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 53eedea073..e80ac933c8 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.UI Anchor = Anchor.Centre; Origin = Anchor.Centre; - Add(new Drawable[] + AddRange(new Drawable[] { connectionLayer = new FollowPointRenderer { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs index 709343d086..3f8249f5a9 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces { EarlyActivationMilliseconds = pre_beat_transition_time; - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { background = new CircularContainer { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 0ad7969c78..bb679e5150 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Taiko.UI public TaikoPlayfield() { - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { new ScaleFixContainer { diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index f4ac01c0f1..cfa98da3c8 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -140,7 +140,7 @@ namespace osu.Game.Beatmaps.Drawables }, starCounter = new StarCounter { - Count = (float)beatmap.StarDifficulty, + CountStars = (float)beatmap.StarDifficulty, Scale = new Vector2(0.8f), } } diff --git a/osu.Game/Database/BeatmapMetadata.cs b/osu.Game/Database/BeatmapMetadata.cs index 04700b3caa..ccf1a99c2c 100644 --- a/osu.Game/Database/BeatmapMetadata.cs +++ b/osu.Game/Database/BeatmapMetadata.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Linq; +using Newtonsoft.Json; using SQLite.Net.Attributes; namespace osu.Game.Database @@ -17,8 +18,13 @@ namespace osu.Game.Database public string TitleUnicode { get; set; } public string Artist { get; set; } public string ArtistUnicode { get; set; } + + [JsonProperty(@"creator")] public string Author { get; set; } + public string Source { get; set; } + + [JsonProperty(@"tags")] public string Tags { get; set; } public int PreviewTime { get; set; } public string AudioFile { get; set; } @@ -35,4 +41,4 @@ namespace osu.Game.Database Tags }.Where(s => !string.IsNullOrEmpty(s)).ToArray(); } -} \ No newline at end of file +} diff --git a/osu.Game/Database/BeatmapOnlineInfo.cs b/osu.Game/Database/BeatmapOnlineInfo.cs index bcb2ef16ac..f4e70388f5 100644 --- a/osu.Game/Database/BeatmapOnlineInfo.cs +++ b/osu.Game/Database/BeatmapOnlineInfo.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using Newtonsoft.Json; -using System.Collections.Generic; namespace osu.Game.Database { @@ -11,28 +10,16 @@ namespace osu.Game.Database /// public class BeatmapOnlineInfo { - /// - /// The different sizes of cover art for this beatmap: cover, cover@2x, card, card@2x, list, list@2x. - /// - [JsonProperty(@"covers")] - public IEnumerable Covers { get; set; } - - /// - /// A small sample clip of this beatmap's song. - /// - [JsonProperty(@"previewUrl")] - public string Preview { get; set; } - /// /// The amount of plays this beatmap has. /// - [JsonProperty(@"play_count")] + [JsonProperty(@"playcount")] public int PlayCount { get; set; } /// - /// The amount of people who have favourited this map. + /// The amount of passes this beatmap has. /// - [JsonProperty(@"favourite_count")] - public int FavouriteCount { get; set; } + [JsonProperty(@"passcount")] + public int PassCount { get; set; } } } diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs index aa5fa21394..017a489d9e 100644 --- a/osu.Game/Database/BeatmapSetInfo.cs +++ b/osu.Game/Database/BeatmapSetInfo.cs @@ -24,6 +24,9 @@ namespace osu.Game.Database [OneToMany(CascadeOperations = CascadeOperation.All)] public List Beatmaps { get; set; } + [Ignore] + public BeatmapSetOnlineInfo OnlineInfo { get; set; } + public double MaxStarDifficulty => Beatmaps.Max(b => b.StarDifficulty); [Indexed] diff --git a/osu.Game/Database/BeatmapSetOnlineInfo.cs b/osu.Game/Database/BeatmapSetOnlineInfo.cs new file mode 100644 index 0000000000..61d408c94a --- /dev/null +++ b/osu.Game/Database/BeatmapSetOnlineInfo.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; + +namespace osu.Game.Database +{ + /// + /// Beatmap set info retrieved for previewing locally without having the set downloaded. + /// + public class BeatmapSetOnlineInfo + { + /// + /// The different sizes of cover art for this beatmap set. + /// + [JsonProperty(@"covers")] + public BeatmapSetOnlineCovers Covers { get; set; } + + /// + /// A small sample clip of this beatmap set's song. + /// + [JsonProperty(@"previewUrl")] + public string Preview { get; set; } + + /// + /// The amount of plays this beatmap set has. + /// + [JsonProperty(@"play_count")] + public int PlayCount { get; set; } + + /// + /// The amount of people who have favourited this beatmap set. + /// + [JsonProperty(@"favourite_count")] + public int FavouriteCount { get; set; } + } + + public class BeatmapSetOnlineCovers + { + public string CoverLowRes { get; set; } + + [JsonProperty(@"cover@2x")] + public string Cover { get; set; } + + public string CardLowRes { get; set; } + + [JsonProperty(@"card@2x")] + public string Card { get; set; } + + public string ListLowRes { get; set; } + + [JsonProperty(@"list@2x")] + public string List { get; set; } + } +} diff --git a/osu.Game/Database/OnlineWorkingBeatmap.cs b/osu.Game/Database/OnlineWorkingBeatmap.cs deleted file mode 100644 index 1465c59434..0000000000 --- a/osu.Game/Database/OnlineWorkingBeatmap.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Linq; -using osu.Framework.Audio.Track; -using osu.Framework.Graphics.Textures; -using osu.Game.Beatmaps; - -namespace osu.Game.Database -{ - internal class OnlineWorkingBeatmap : WorkingBeatmap - { - private readonly TextureStore textures; - private readonly TrackManager tracks; - - public OnlineWorkingBeatmap(BeatmapInfo beatmapInfo, TextureStore textures, TrackManager tracks) : base(beatmapInfo) - { - this.textures = textures; - this.tracks = tracks; - } - - protected override Beatmap GetBeatmap() - { - return new Beatmap(); - } - - protected override Texture GetBackground() - { - return textures.Get(BeatmapInfo.OnlineInfo.Covers.FirstOrDefault()); - } - - protected override Track GetTrack() - { - return tracks.Get(BeatmapInfo.OnlineInfo.Preview); - } - } -} diff --git a/osu.Game/Graphics/Containers/ReverseDepthFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs similarity index 66% rename from osu.Game/Graphics/Containers/ReverseDepthFillFlowContainer.cs rename to osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index 0b38bf5fe0..781e149078 100644 --- a/osu.Game/Graphics/Containers/ReverseDepthFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs @@ -8,9 +8,10 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Graphics.Containers { - public class ReverseDepthFillFlowContainer : FillFlowContainer where T : Drawable + public class ReverseChildIDFillFlowContainer : FillFlowContainer where T : Drawable { - protected override IComparer DepthComparer => new ReverseCreationOrderDepthComparer(); + protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); + protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); } } diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index 5fdb5e869e..1d792f1b78 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.Containers sections = value.ToList(); if (sections.Count == 0) return; - sectionsContainer.Add(sections); + sectionsContainer.AddRange(sections); SelectedSection.Value = sections[0]; lastKnownScroll = float.NaN; } diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index e4a471bbba..87b4ab9e40 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -58,7 +58,7 @@ namespace osu.Game.Graphics.UserInterface Direction = Direction, }); //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards - Remove(Children.Where((bar, index) => index >= value.Count()).ToList()); + RemoveRange(Children.Where((bar, index) => index >= value.Count()).ToList()); } } } diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 6814308cb4..18156f8e76 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -49,7 +49,7 @@ namespace osu.Game.Graphics.UserInterface Content.Masking = true; Content.CornerRadius = 5; - Add(new Drawable[] + AddRange(new Drawable[] { new Triangles { diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 39db8d8be7..0d852e4276 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -17,7 +17,7 @@ namespace osu.Game.Graphics.UserInterface public SearchTextBox() { Height = 35; - Add(new Drawable[] + AddRange(new Drawable[] { new TextAwesome { diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs index 295cdac81d..490ea6e64a 100644 --- a/osu.Game/Graphics/UserInterface/StarCounter.cs +++ b/osu.Game/Graphics/UserInterface/StarCounter.cs @@ -33,25 +33,25 @@ namespace osu.Game.Graphics.UserInterface private const float star_size = 20; private const float star_spacing = 4; - private float count; + private float countStars; /// /// Amount of stars represented. /// - public float Count + public float CountStars { get { - return count; + return countStars; } set { - if (count == value) return; + if (countStars == value) return; if (IsLoaded) transformCount(value); - count = value; + countStars = value; } } @@ -94,15 +94,15 @@ namespace osu.Game.Graphics.UserInterface public void ResetCount() { - count = 0; + countStars = 0; StopAnimation(); } public void ReplayAnimation() { - var t = count; + var t = countStars; ResetCount(); - Count = t; + CountStars = t; } public void StopAnimation() @@ -111,8 +111,8 @@ namespace osu.Game.Graphics.UserInterface foreach (var star in stars.Children) { star.ClearTransforms(true); - star.FadeTo(i < count ? 1.0f : minStarAlpha); - star.Icon.ScaleTo(getStarScale(i, count)); + star.FadeTo(i < countStars ? 1.0f : minStarAlpha); + star.Icon.ScaleTo(getStarScale(i, countStars)); i++; } } @@ -132,7 +132,7 @@ namespace osu.Game.Graphics.UserInterface { star.ClearTransforms(true); - var delay = (count <= newValue ? Math.Max(i - count, 0) : Math.Max(count - 1 - i, 0)) * animationDelay; + var delay = (countStars <= newValue ? Math.Max(i - countStars, 0) : Math.Max(countStars - 1 - i, 0)) * animationDelay; using (BeginDelayedSequence(delay, true)) { diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs new file mode 100644 index 0000000000..f6f9bf69fd --- /dev/null +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using osu.Game.Database; +using osu.Game.Overlays; +using osu.Game.Overlays.Direct; + +namespace osu.Game.Online.API.Requests +{ + public class GetBeatmapSetsRequest : APIRequest> + { + private readonly string query; + private readonly RulesetInfo ruleset; + private readonly RankStatus rankStatus; + private readonly DirectSortCriteria sortCriteria; + private readonly SortDirection direction; + private string directionString => direction == SortDirection.Descending ? @"desc" : @"asc"; + + public GetBeatmapSetsRequest(string query, RulesetInfo ruleset, RankStatus rankStatus = RankStatus.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) + { + this.query = System.Uri.EscapeDataString(query); + this.ruleset = ruleset; + this.rankStatus = rankStatus; + this.sortCriteria = sortCriteria; + this.direction = direction; + } + + protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; + } + + public class GetBeatmapSetsResponse : BeatmapMetadata + { + [JsonProperty(@"covers")] + private BeatmapSetOnlineCovers covers { get; set; } + + [JsonProperty(@"previewUrl")] + private string preview { get; set; } + + [JsonProperty(@"play_count")] + private int playCount { get; set; } + + [JsonProperty(@"favourite_count")] + private int favouriteCount { get; set; } + + [JsonProperty(@"beatmaps")] + private IEnumerable beatmaps { get; set; } + + public BeatmapSetInfo ToBeatmapSet(RulesetDatabase rulesets) + { + return new BeatmapSetInfo + { + Metadata = this, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = covers, + Preview = preview, + PlayCount = playCount, + FavouriteCount = favouriteCount, + }, + Beatmaps = beatmaps.Select(b => b.ToBeatmap(rulesets)).ToList(), + }; + } + + private class GetBeatmapSetsBeatmapResponse : BeatmapMetadata + { + [JsonProperty(@"playcount")] + private int playCount { get; set; } + + [JsonProperty(@"passcount")] + private int passCount { get; set; } + + [JsonProperty(@"mode_int")] + private int ruleset { get; set; } + + [JsonProperty(@"difficulty_rating")] + private double starDifficulty { get; set; } + + public BeatmapInfo ToBeatmap(RulesetDatabase rulesets) + { + return new BeatmapInfo + { + Metadata = this, + Ruleset = rulesets.GetRuleset(ruleset), + StarDifficulty = starDifficulty, + OnlineInfo = new BeatmapOnlineInfo + { + PlayCount = playCount, + PassCount = passCount, + }, + }; + } + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 7e5b913d10..961e296050 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -141,7 +141,7 @@ namespace osu.Game { base.LoadComplete(); - Add(new Drawable[] { + AddRange(new Drawable[] { new VolumeControlReceptor { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index e8bde11a3c..f8b7c7e581 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Chat var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY)); //up to last Channel.MAX_HISTORY messages - flow.Add(displayMessages.Select(m => new ChatLine(m))); + flow.AddRange(displayMessages.Select(m => new ChatLine(m))); if (!IsLoaded) return; diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index a670b27540..3c464af05d 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -1,14 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; using osu.Game.Database; using osu.Game.Graphics; @@ -50,7 +48,7 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load(OsuColour colours, LocalisationEngine localisation, TextureStore textures) + private void load(OsuColour colours, LocalisationEngine localisation) { Children = new[] { @@ -59,7 +57,7 @@ namespace osu.Game.Overlays.Direct RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - GetBackground(textures), + CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -180,11 +178,11 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = vertical_padding, Right = vertical_padding }, Children = new[] { - new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0) + new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0) { Margin = new MarginPadding { Right = 1 }, }, - new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0), + new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, }; diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 1e923d79fa..f693998563 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -12,8 +12,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Database; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Framework.Graphics.Textures; -using System.Linq; using osu.Framework.Input; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; @@ -49,7 +47,7 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load(LocalisationEngine localisation, TextureStore textures) + private void load(LocalisationEngine localisation) { Children = new[] { @@ -58,7 +56,7 @@ namespace osu.Game.Overlays.Direct RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - GetBackground(textures), + CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -105,11 +103,11 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding }, Children = new Drawable[] { - new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0) + new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0) { Margin = new MarginPadding { Right = 1 }, }, - new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0), + new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), new FillFlowContainer { Anchor = Anchor.TopRight, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 3c708bff67..02b6e32192 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,8 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using OpenTK; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -34,21 +34,25 @@ namespace osu.Game.Overlays.Direct return icons; } - protected Drawable GetBackground(TextureStore textures) + protected Drawable CreateBackground() => new DelayedLoadWrapper(new BeatmapSetBackgroundSprite(SetInfo) { - return new AsyncLoadWrapper(new BeatmapBackgroundSprite(new OnlineWorkingBeatmap(SetInfo.Beatmaps.FirstOrDefault(), textures, null)) - { - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out), - }) { RelativeSizeAxes = Axes.Both }; - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out), + }) + { + RelativeSizeAxes = Axes.Both, + TimeBeforeLoad = 300 + }; public class Statistic : FillFlowContainer { private readonly SpriteText text; private int value; + public int Value { get { return value; } @@ -85,5 +89,23 @@ namespace osu.Game.Overlays.Direct Value = value; } } + + private class BeatmapSetBackgroundSprite : Sprite + { + private readonly BeatmapSetInfo set; + public BeatmapSetBackgroundSprite(BeatmapSetInfo set) + { + this.set = set; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + string resource = set.OnlineInfo.Covers.Card; + + if (resource != null) + Texture = textures.Get(resource); + } + } } } diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index b898d24c31..bb6055dc4f 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -14,12 +14,13 @@ using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Direct { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { + public readonly Bindable Ruleset = new Bindable(); private FillFlowContainer modeButtons; protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); - protected override DirectSortCritera DefaultTab => DirectSortCritera.Title; + protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked; protected override Drawable CreateSupplementaryControls() { modeButtons = new FillFlowContainer @@ -36,10 +37,10 @@ namespace osu.Game.Overlays.Direct { DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; - var b = new Bindable(); //backup bindable incase the game is null + Ruleset.BindTo(game?.Ruleset ?? new Bindable() { Value = rulesets.GetRuleset(0) }); foreach (var r in rulesets.AllRulesets) { - modeButtons.Add(new RulesetToggleButton(game?.Ruleset ?? b, r)); + modeButtons.Add(new RulesetToggleButton(Ruleset, r)); } } @@ -95,7 +96,7 @@ namespace osu.Game.Overlays.Direct } } - public enum DirectSortCritera + public enum DirectSortCriteria { Title, Artist, @@ -103,5 +104,6 @@ namespace osu.Game.Overlays.Direct Difficulty, Ranked, Rating, + Plays, } } diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index 000ef473cc..2c50fb453f 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -30,10 +30,10 @@ namespace osu.Game.Overlays.Direct { Search, [Description("Newest Maps")] - NewestMaps, + NewestMaps = DirectSortCriteria.Ranked, [Description("Top Rated")] - TopRated, + TopRated = DirectSortCriteria.Rating, [Description("Most Played")] - MostPlayed + MostPlayed = DirectSortCriteria.Plays, } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index beb1355f36..5fa90ab1d6 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -5,21 +5,28 @@ using System.Collections.Generic; using System.Linq; using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Threading; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.Direct; using osu.Game.Overlays.SearchableList; using OpenTK.Graphics; namespace osu.Game.Overlays { - public class DirectOverlay : SearchableListOverlay + public class DirectOverlay : SearchableListOverlay { private const float panel_padding = 10f; + private APIAccess api; + private RulesetDatabase rulesets; + private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; private readonly FillFlowContainer panels; @@ -29,7 +36,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable beatmapSets; public IEnumerable BeatmapSets @@ -40,6 +47,17 @@ namespace osu.Game.Overlays if (beatmapSets?.Equals(value) ?? false) return; beatmapSets = value; + if (BeatmapSets == null) + { + foreach (var p in panels.Children) + { + p.FadeOut(200); + p.Expire(); + } + + return; + } + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } } @@ -98,22 +116,60 @@ namespace osu.Game.Overlays }, }; - Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; }; Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; }; + ((FilterControl)Filter).Ruleset.ValueChanged += ruleset => Scheduler.AddOnce(updateSearch); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; + Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch); + + Header.Tabs.Current.ValueChanged += tab => + { + if (tab != DirectTab.Search) + { + currentQuery.Value = string.Empty; + Filter.Tabs.Current.Value = (DirectSortCriteria)Header.Tabs.Current.Value; + Scheduler.AddOnce(updateSearch); + } + }; + + currentQuery.ValueChanged += v => + { + queryChangedDebounce?.Cancel(); + + if (string.IsNullOrEmpty(v)) + Scheduler.AddOnce(updateSearch); + else + { + BeatmapSets = null; + ResultAmounts = null; + + queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); + } + }; + + currentQuery.BindTo(Filter.Search.Current); + + Filter.Tabs.Current.ValueChanged += sortCriteria => + { + if (Header.Tabs.Current.Value != DirectTab.Search && sortCriteria != (DirectSortCriteria)Header.Tabs.Current.Value) + Header.Tabs.Current.Value = DirectTab.Search; + + Scheduler.AddOnce(updateSearch); + }; updateResultCounts(); } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, APIAccess api, RulesetDatabase rulesets) { + this.api = api; + this.rulesets = rulesets; resultCountsContainer.Colour = colours.Yellow; } private void updateResultCounts() { - resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.Out); + resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.OutQuint); if (ResultAmounts == null) return; resultCountsText.Text = pluralize("Artist", ResultAmounts.Artists) + ", " + @@ -129,9 +185,68 @@ namespace osu.Game.Overlays private void recreatePanels(PanelDisplayStyle displayStyle) { if (BeatmapSets == null) return; - panels.ChildrenEnumerable = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b)); + + panels.ChildrenEnumerable = BeatmapSets.Select(b => + { + switch (displayStyle) + { + case PanelDisplayStyle.Grid: + return new DirectGridPanel(b) { Width = 400 }; + default: + return new DirectListPanel(b); + } + }); } + private GetBeatmapSetsRequest getSetsRequest; + + private readonly Bindable currentQuery = new Bindable(); + + private ScheduledDelegate queryChangedDebounce; + + private void updateSearch() + { + queryChangedDebounce?.Cancel(); + + if (!IsLoaded) return; + + BeatmapSets = null; + ResultAmounts = null; + + getSetsRequest?.Cancel(); + + if (api == null) return; + + if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return; + + getSetsRequest = new GetBeatmapSetsRequest(currentQuery, + ((FilterControl)Filter).Ruleset.Value, + Filter.DisplayStyleControl.Dropdown.Current.Value, + Filter.Tabs.Current.Value); //todo: sort direction (?) + + getSetsRequest.Success += r => + { + BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets)); + if (BeatmapSets == null) return; + + var artists = new List(); + var songs = new List(); + var tags = new List(); + foreach (var s in BeatmapSets) + { + artists.Add(s.Metadata.Artist); + songs.Add(s.Metadata.Title); + tags.AddRange(s.Metadata.Tags.Split(' ')); + } + + ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); + }; + + api.Queue(getSetsRequest); + } + + private int distinctCount(List list) => list.Distinct().ToArray().Length; + public class ResultCounts { public readonly int Artists; diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index a7e7bb53b5..aca73d2828 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -199,7 +199,7 @@ namespace osu.Game.Overlays.Mods iconsContainer.Clear(); if (Mods.Length > 1) { - iconsContainer.Add(new[] + iconsContainer.AddRange(new[] { backgroundIcon = new ModIcon(Mods[1]) { diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 74cced5ee9..f5613d6656 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Notifications RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { Light = new NotificationLight { diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index b4f35be733..831b09e7e9 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Notifications Left = 20, }; - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { new Container { diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 2ac93b2ada..42604658de 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Notifications public SimpleNotification() { - IconContent.Add(new Drawable[] + IconContent.AddRange(new Drawable[] { IconBackgound = new Box { diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 8db802ad3d..8d7d1ce994 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -120,6 +120,7 @@ namespace osu.Game.Overlays.SearchableList { protected override Color4 BackgroundUnfocused => backgroundColour; protected override Color4 BackgroundFocused => backgroundColour; + protected override bool AllowCommit => true; private Color4 backgroundColour; diff --git a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs index 6c0887b5df..e2eec0214f 100644 --- a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.SearchableList { public SlimMenu() { - Background.Colour = Color4.Black.Opacity(0.25f); + Background.Colour = Color4.Black.Opacity(0.7f); } } } diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index 2e3dc1ada2..77bf87f718 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Settings const int header_size = 26; const int header_margin = 25; const int border_size = 2; - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { new Box { diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 14082aa4db..0a9f7ba5d0 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Settings RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { new OsuSpriteText { diff --git a/osu.Game/Rulesets/Objects/HitObjectStartTimeComparer.cs b/osu.Game/Rulesets/Objects/HitObjectStartTimeComparer.cs deleted file mode 100644 index b089856dcb..0000000000 --- a/osu.Game/Rulesets/Objects/HitObjectStartTimeComparer.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; -using osu.Game.Rulesets.Objects.Drawables; - -namespace osu.Game.Rulesets.Objects -{ - /// - /// Compares two hit objects by their start time, falling back to creation order if their start time is equal. - /// - public class HitObjectStartTimeComparer : Drawable.CreationOrderDepthComparer - { - public override int Compare(Drawable x, Drawable y) - { - var hitObjectX = x as DrawableHitObject; - var hitObjectY = y as DrawableHitObject; - - // If either of the two drawables are not hit objects, fall back to the base comparer - if (hitObjectX?.HitObject == null || hitObjectY?.HitObject == null) - return base.Compare(x, y); - - // Compare by start time - int i = hitObjectX.HitObject.StartTime.CompareTo(hitObjectY.HitObject.StartTime); - if (i != 0) - return i; - - return base.Compare(x, y); - } - } - - /// - /// Compares two hit objects by their start time, falling back to creation order if their start time is equal. - /// This will compare the two hit objects in reverse order. - /// - public class HitObjectReverseStartTimeComparer : Drawable.ReverseCreationOrderDepthComparer - { - public override int Compare(Drawable x, Drawable y) - { - var hitObjectX = x as DrawableHitObject; - var hitObjectY = y as DrawableHitObject; - - // If either of the two drawables are not hit objects, fall back to the base comparer - if (hitObjectX?.HitObject == null || hitObjectY?.HitObject == null) - return base.Compare(x, y); - - // Compare by start time - int i = hitObjectY.HitObject.StartTime.CompareTo(hitObjectX.HitObject.StartTime); - if (i != 0) - return i; - - return base.Compare(x, y); - } - } -} \ No newline at end of file diff --git a/osu.Game/Rulesets/Timing/DrawableTimingSection.cs b/osu.Game/Rulesets/Timing/DrawableTimingSection.cs index 589ee9991d..6345a566c2 100644 --- a/osu.Game/Rulesets/Timing/DrawableTimingSection.cs +++ b/osu.Game/Rulesets/Timing/DrawableTimingSection.cs @@ -1,13 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using System.Linq; using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using osu.Game.Rulesets.Objects.Types; @@ -55,7 +53,22 @@ namespace osu.Game.Rulesets.Timing /// internal MultiplierControlPoint ControlPoint; - protected override IComparer DepthComparer => new HitObjectReverseStartTimeComparer(); + protected override int Compare(Drawable x, Drawable y) + { + var xHitObject = x as DrawableHitObject; + var yHitObject = y as DrawableHitObject; + + // If either of the two drawables are not hit objects, fall back to the base comparer + if (xHitObject?.HitObject == null || yHitObject?.HitObject == null) + return base.Compare(x, y); + + // Compare by start time + int i = yHitObject.HitObject.StartTime.CompareTo(xHitObject.HitObject.StartTime); + if (i != 0) + return i; + + return base.Compare(x, y); + } /// /// Creates a new . diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentCollection.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentCollection.cs index 1323bb14a1..22213be740 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentCollection.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentCollection.cs @@ -33,7 +33,20 @@ namespace osu.Game.Rulesets.Timing set { visibleTimeRange.BindTo(value); } } - protected override IComparer DepthComparer => new SpeedAdjustmentContainerReverseStartTimeComparer(); + protected override int Compare(Drawable x, Drawable y) + { + var xSpeedAdjust = x as SpeedAdjustmentContainer; + var ySpeedAdjust = y as SpeedAdjustmentContainer; + + // If either of the two drawables are not hit objects, fall back to the base comparer + if (xSpeedAdjust?.ControlPoint == null || ySpeedAdjust?.ControlPoint == null) + return CompareReverseChildID(x, y); + + // Compare by start time + int i = ySpeedAdjust.ControlPoint.StartTime.CompareTo(xSpeedAdjust.ControlPoint.StartTime); + + return i != 0 ? i : CompareReverseChildID(x, y); + } /// /// Hit objects that are to be re-processed on the next update. @@ -116,27 +129,5 @@ namespace osu.Game.Rulesets.Timing /// The time to find the active at. /// The active at . Null if there are no speed adjustments. private SpeedAdjustmentContainer adjustmentContainerAt(double time) => Children.FirstOrDefault(c => c.CanContain(time)) ?? Children.LastOrDefault(); - - /// - /// Compares two speed adjustment containers by their control point start time, falling back to creation order - // if their control point start time is equal. This will compare the two speed adjustment containers in reverse order. - /// - private class SpeedAdjustmentContainerReverseStartTimeComparer : ReverseCreationOrderDepthComparer - { - public override int Compare(Drawable x, Drawable y) - { - var speedAdjustmentX = x as SpeedAdjustmentContainer; - var speedAdjustmentY = y as SpeedAdjustmentContainer; - - // If either of the two drawables are not hit objects, fall back to the base comparer - if (speedAdjustmentX?.ControlPoint == null || speedAdjustmentY?.ControlPoint == null) - return base.Compare(x, y); - - // Compare by start time - int i = speedAdjustmentY.ControlPoint.StartTime.CompareTo(speedAdjustmentX.ControlPoint.StartTime); - - return i != 0 ? i : base.Compare(x, y); - } - } } } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index fd87fd1b38..24fee10195 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -114,8 +114,8 @@ namespace osu.Game.Screens.Menu buttonsTopLevel.Add(new Button(@"osu!direct", string.Empty, FontAwesome.fa_osu_chevron_down_o, new Color4(165, 204, 0, 255), () => OnDirect?.Invoke(), 0, Key.D)); buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), onExit, 0, Key.Q)); - buttonFlow.Add(buttonsPlay); - buttonFlow.Add(buttonsTopLevel); + buttonFlow.AddRange(buttonsPlay); + buttonFlow.AddRange(buttonsTopLevel); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index d0972ea84b..071de99209 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Menu /// public Drawable CentreTarget; - protected override IComparer DepthComparer => new ReverseCreationOrderDepthComparer(); + protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); diff --git a/osu.Game/Screens/Multiplayer/RoomInspector.cs b/osu.Game/Screens/Multiplayer/RoomInspector.cs index 4c1675b607..322d74f2b3 100644 --- a/osu.Game/Screens/Multiplayer/RoomInspector.cs +++ b/osu.Game/Screens/Multiplayer/RoomInspector.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; using osu.Game.Beatmaps.Drawables; @@ -46,7 +47,6 @@ namespace osu.Game.Screens.Multiplayer private OsuColour colours; private LocalisationEngine localisation; - private TextureStore textures; private Room room; @@ -278,11 +278,10 @@ namespace osu.Game.Screens.Multiplayer } [BackgroundDependencyLoader] - private void load(OsuColour colours, LocalisationEngine localisation, TextureStore textures) + private void load(OsuColour colours, LocalisationEngine localisation) { this.localisation = localisation; this.colours = colours; - this.textures = textures; beatmapAuthor.Colour = colours.Gray9; @@ -333,7 +332,7 @@ namespace osu.Game.Screens.Multiplayer coverContainer.FadeIn(transition_duration); coverContainer.Children = new[] { - new AsyncLoadWrapper(new BeatmapBackgroundSprite(new OnlineWorkingBeatmap(value, textures, null)) + new AsyncLoadWrapper(new CoverSprite(value.BeatmapSet) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -410,5 +409,22 @@ namespace osu.Game.Screens.Multiplayer }; } } + + private class CoverSprite : Sprite + { + private readonly BeatmapSetInfo set; + + public CoverSprite(BeatmapSetInfo set) + { + this.set = set; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + if (set.OnlineInfo?.Covers?.Cover != null) + Texture = textures.Get(set.OnlineInfo.Covers.Cover); + } + } } } diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 921accf6ac..4cbea43ac5 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD { Children = new Drawable[] { - iconsContainer = new ReverseDepthFillFlowContainer + iconsContainer = new ReverseChildIDFillFlowContainer { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs index 20a8f73104..e507055d5f 100644 --- a/osu.Game/Screens/Play/KeyCounter.cs +++ b/osu.Game/Screens/Play/KeyCounter.cs @@ -20,15 +20,15 @@ namespace osu.Game.Screens.Play private SpriteText countSpriteText; public bool IsCounting { get; set; } - private int count; - public int Count + private int countPresses; + public int CountPresses { - get { return count; } + get { return countPresses; } private set { - if (count != value) + if (countPresses != value) { - count = value; + countPresses = value; countSpriteText.Text = value.ToString(@"#,0"); } } @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Play isLit = value; updateGlowSprite(value); if (value && IsCounting) - Count++; + CountPresses++; } } } @@ -98,7 +98,7 @@ namespace osu.Game.Screens.Play }, countSpriteText = new OsuSpriteText { - Text = Count.ToString(@"#,0"), + Text = CountPresses.ToString(@"#,0"), Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativePositionAxes = Axes.Both, @@ -128,6 +128,6 @@ namespace osu.Game.Screens.Play } } - public void ResetCount() => Count = 0; + public void ResetCount() => CountPresses = 0; } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d0ffe1de1c..b0d3a99603 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -200,7 +200,7 @@ namespace osu.Game.Screens.Play scoreProcessor = HitRenderer.CreateScoreProcessor(); - hudOverlay.KeyCounter.Add(rulesetInstance.CreateGameplayKeys()); + hudOverlay.KeyCounter.AddRange(rulesetInstance.CreateGameplayKeys()); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindHitRenderer(HitRenderer); diff --git a/osu.Game/Screens/Ranking/ResultsPage.cs b/osu.Game/Screens/Ranking/ResultsPage.cs index d0a1c49119..59173748ed 100644 --- a/osu.Game/Screens/Ranking/ResultsPage.cs +++ b/osu.Game/Screens/Ranking/ResultsPage.cs @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Ranking [BackgroundDependencyLoader] private void load(OsuColour colours) { - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { fill = new Box { diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index f9064c4963..647cac5bbe 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -12,7 +12,6 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Configuration; using osu.Framework.Input; using OpenTK.Input; -using System.Collections; using osu.Framework.MathUtils; using System.Diagnostics; using System.Threading.Tasks; @@ -22,7 +21,7 @@ using osu.Framework.Configuration; namespace osu.Game.Screens.Select { - internal class BeatmapCarousel : ScrollContainer, IEnumerable + internal class BeatmapCarousel : ScrollContainer { public BeatmapInfo SelectedBeatmap => selectedPanel?.Beatmap; @@ -265,10 +264,6 @@ namespace osu.Game.Screens.Select perform(); } - public IEnumerator GetEnumerator() => groups.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - private BeatmapGroup createGroup(BeatmapSetInfo beatmapSet) { foreach (var b in beatmapSet.Beatmaps) @@ -307,7 +302,7 @@ namespace osu.Game.Screens.Select panels.Remove(p); scrollableContent.Remove(group.Header); - scrollableContent.Remove(group.BeatmapPanels); + scrollableContent.RemoveRange(group.BeatmapPanels); if (selectedGroup == group) SelectNext(); diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index d116e5b159..47d25585ad 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Select public BeatmapDetailArea() { - AddInternal(new Drawable[] + AddRangeInternal(new Drawable[] { new BeatmapDetailAreaTabControl { @@ -61,7 +61,7 @@ namespace osu.Game.Screens.Select }, }); - Add(new Drawable[] + AddRange(new Drawable[] { Details = new BeatmapDetails { diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index f18080d6f5..6345807ea3 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -70,7 +70,7 @@ namespace osu.Game.Screens.Select.Options Scale = new Vector2(1, 0), Colour = Color4.Black.Opacity(0.5f), }, - buttonsContainer = new ReverseDepthFillFlowContainer + buttonsContainer = new ReverseChildIDFillFlowContainer { Height = height, RelativePositionAxes = Axes.X, diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b0bc5dfd34..fc21cbafc0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -190,7 +190,6 @@ - @@ -474,10 +473,11 @@ - - + + +