From 8e685a98d47a5f094c8ce0555508552b6caae5a9 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 26 Jul 2017 18:55:37 +0200 Subject: [PATCH 01/90] add RanksSection --- .../Tests/TestCaseUserRanks.cs | 100 +++++++++ .../osu.Desktop.VisualTests.csproj | 1 + .../Profile/Sections/Ranks/DrawablePlay.cs | 211 ++++++++++++++++++ .../Overlays/Profile/Sections/Ranks/Play.cs | 21 ++ .../Overlays/Profile/Sections/RanksSection.cs | 68 ++++++ osu.Game/osu.Game.csproj | 2 + 6 files changed, 403 insertions(+) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/Play.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs new file mode 100644 index 0000000000..651c39ede4 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -0,0 +1,100 @@ +// 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.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Database; +using osu.Game.Graphics; +using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Ranks; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Scoring; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Desktop.VisualTests.Tests +{ + public class TestCaseUserRanks : TestCase + { + public override string Description => "showing your latest achievements"; + + public TestCaseUserRanks() + { + RanksSection ranks; + + Add(new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + ranks = new RanksSection(), + } + }); + + AddStep("Add First Place", () => ranks.FirstPlacePlays = new[] + { + new Play + { + Rank = ScoreRank.A, + PerformancePoints = 666, + Accuracy = 0.735, + Date = DateTimeOffset.UtcNow, + Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime() }, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "FREEDOM DiVE", + Artist = "xi" + }, + Version = "FOUR DIMENSIONS", + OnlineBeatmapID = 129891, + } + } + }); + + AddStep("Add Best Performances", () => + { + List plays = new List(); + Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; + List selectedMods = new List(availableMods); + for (int i = 0; i <= availableMods.Length; i++) + { + plays.Add(new Play + { + Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), + PerformancePoints = (int)(Math.Pow(0.50, i) * 800), + Accuracy = Math.Pow(0.99, i), + Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), + Mods = selectedMods.ToList(), + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "Highscore", + Artist = "Panda Eyes & Teminite" + }, + Version = "Game Over", + OnlineBeatmapID = 736215, + } + }); + if(i < availableMods.Length) + selectedMods.Remove(availableMods[i]); + } + ranks.BestPlays = plays; + }); + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 4974f0c0d1..00bcaca1e8 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -217,6 +217,7 @@ + diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs new file mode 100644 index 0000000000..66588462f3 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs @@ -0,0 +1,211 @@ +// 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 OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Select.Leaderboards; +using System.Linq; +using OpenTK.Graphics; +using System.Diagnostics; +using osu.Framework.Input; +using osu.Framework.Localisation; + +namespace osu.Game.Overlays.Profile.Sections.Ranks +{ + public class DrawablePlay : Container + { + private readonly FillFlowContainer stats; + private readonly FillFlowContainer metadata; + private readonly ModContainer modContainer; + private readonly Play play; + private readonly double weight; + + public DrawablePlay(Play play, double weight = -1) + { + this.play = play; + this.weight = weight; + + Children = new Drawable[] + { + new DrawableRank(play.Rank) + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }, + stats = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Vertical, + }, + metadata = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 70 }, + Direction = FillDirection.Vertical, + Child = new OsuSpriteText + { + Text = play.Date.LocalDateTime.ToShortDateString(), + TextSize = 11, + Colour = OsuColour.Gray(0xAA), + Depth = -1, + }, + }, + modContainer = new ModContainer + { + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Width = 60, + Margin = new MarginPadding{ Right = 140 } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour, LocalisationEngine locale) + { + stats.Add(new OsuSpriteText { + Text = play.PerformancePoints + "pp", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + TextSize = 18, + Font = "Exo2.0-BoldItalic", + }); + if(weight != -1) + { + stats.Add(new OsuSpriteText + { + Text = $"weighted: {(int)(play.PerformancePoints * weight)}pp ({weight.ToString("0%")})", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Colour = colour.GrayA, + TextSize = 11, + Font = "Exo2.0-RegularItalic", + }); + } + stats.Add(new OsuSpriteText { + Text = "accuracy: " + play.Accuracy.ToString("0.00%"), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Colour = colour.GrayA, + TextSize = 11, + Font = "Exo2.0-RegularItalic", + }); + + metadata.Add(new LinkContainer + { + AutoSizeAxes = Axes.Both, + Url = $"https://osu.ppy.sh/beatmaps/{play.Beatmap.OnlineBeatmapID}", + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new OsuSpriteText + { + Current = locale.GetUnicodePreference($"{play.Beatmap.Metadata.TitleUnicode ?? play.Beatmap.Metadata.Title} [{play.Beatmap.Version}] ", $"{play.Beatmap.Metadata.Title ?? play.Beatmap.Metadata.TitleUnicode} [{play.Beatmap.Version}] "), + TextSize = 15, + Font = "Exo2.0-SemiBoldItalic", + }, + new OsuSpriteText + { + Current = locale.GetUnicodePreference(play.Beatmap.Metadata.ArtistUnicode, play.Beatmap.Metadata.Artist), + TextSize = 12, + Padding = new MarginPadding { Top = 3 }, + Font = "Exo2.0-RegularItalic", + }, + }, + }, + }); + + foreach (Mod mod in play.Mods) + modContainer.Add(new ModIcon(mod.Icon, colour.Yellow)); + } + + private class ModContainer : FlowContainer + { + protected override IEnumerable ComputeLayoutPositions() + { + int count = FlowingChildren.Count(); + for (int i = 0; i < count; i++) + yield return new Vector2(DrawWidth * i * (count == 1 ? 0 : 1f / (count - 1)), 0); + } + } + + private class ModIcon : Container + { + public ModIcon(FontAwesome icon, Color4 colour) + { + AutoSizeAxes = Axes.Both; + + Children = new[] + { + new TextAwesome + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Icon = FontAwesome.fa_osu_mod_bg, + Colour = colour, + Shadow = true, + TextSize = 30, + UseFullGlyphHeight = false, + }, + new TextAwesome + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Icon = icon, + Colour = OsuColour.Gray(84), + TextSize = 18, + Position = new Vector2(0f, 2f), + UseFullGlyphHeight = false, + }, + }; + } + } + + private class LinkContainer : OsuClickableContainer + { + public string Url; + + private Color4 hoverColour; + + public LinkContainer() + { + Action = () => Process.Start(Url); + } + + protected override bool OnHover(InputState state) + { + this.FadeColour(hoverColour, 500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + this.FadeColour(Color4.White, 500, Easing.OutQuint); + base.OnHoverLost(state); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverColour = colours.Yellow; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs b/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs new file mode 100644 index 0000000000..a9cbbcbef4 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Database; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using System; +using System.Collections.Generic; + +namespace osu.Game.Overlays.Profile.Sections.Ranks +{ + public class Play + { + public ScoreRank Rank; + public BeatmapInfo Beatmap; + public DateTimeOffset Date; + public IEnumerable Mods; + public int PerformancePoints; + public double Accuracy; + } +} diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 5ea135fcac..f19de5356c 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -1,6 +1,13 @@ // 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.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Profile.Sections.Ranks; +using System; +using System.Collections.Generic; + namespace osu.Game.Overlays.Profile.Sections { public class RanksSection : ProfileSection @@ -8,5 +15,66 @@ namespace osu.Game.Overlays.Profile.Sections public override string Title => "Ranks"; public override string Identifier => "top_ranks"; + + private readonly FillFlowContainer best, firstPlace; + + public RanksSection() + { + Children = new Drawable[] + { + new OsuSpriteText { + TextSize = 15, + Text = "Best Performance", + Font = "Exo2.0-RegularItalic", + }, + best = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + }, + new OsuSpriteText { + TextSize = 15, + Text = "First Place Ranks", + Font = "Exo2.0-RegularItalic", + }, + firstPlace = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + }, + }; + } + + public IEnumerable BestPlays + { + set + { + int i = 0; + foreach (Play play in value) + { + best.Add(new DrawablePlay(play, Math.Pow(0.95, i)) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + i++; + } + } + } + + public IEnumerable FirstPlacePlays + { + set + { + foreach (Play play in value) + firstPlace.Add(new DrawablePlay(play) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + } + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6031304b26..b63ad6a271 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -98,6 +98,8 @@ + + From 7b8997cfc2ea6bd9f11d72c8dc49c84d9519d680 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 26 Jul 2017 19:42:34 +0200 Subject: [PATCH 02/90] CI stuff --- osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs | 2 -- osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs index 651c39ede4..d3d0ae4577 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -15,8 +15,6 @@ using osu.Game.Rulesets.Scoring; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace osu.Desktop.VisualTests.Tests { diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs index 66588462f3..5b3bbff3ca 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs @@ -16,6 +16,7 @@ using OpenTK.Graphics; using System.Diagnostics; using osu.Framework.Input; using osu.Framework.Localisation; +using System.Globalization; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -89,7 +90,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"weighted: {(int)(play.PerformancePoints * weight)}pp ({weight.ToString("0%")})", + Text = $"weighted: {(int)(play.PerformancePoints * weight)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, From 0fc36065f4be114dac08559d7ee265d4dcda6118 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 00:31:52 +0200 Subject: [PATCH 03/90] replace `Play` with `Score` --- .../Tests/TestCaseUserRanks.cs | 14 +++++----- .../Profile/Sections/Ranks/DrawablePlay.cs | 27 ++++++++++--------- .../Overlays/Profile/Sections/Ranks/Play.cs | 21 --------------- .../Overlays/Profile/Sections/RanksSection.cs | 19 ++++++------- osu.Game/Rulesets/Scoring/Score.cs | 2 ++ osu.Game/osu.Game.csproj | 1 - 6 files changed, 32 insertions(+), 52 deletions(-) delete mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/Play.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs index d3d0ae4577..9eacde0b97 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -41,12 +41,11 @@ namespace osu.Desktop.VisualTests.Tests } }); - AddStep("Add First Place", () => ranks.FirstPlacePlays = new[] + AddStep("Add First Place", () => ranks.FirstPlaceScores = new[] { - new Play + new Score { Rank = ScoreRank.A, - PerformancePoints = 666, Accuracy = 0.735, Date = DateTimeOffset.UtcNow, Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime() }, @@ -65,18 +64,17 @@ namespace osu.Desktop.VisualTests.Tests AddStep("Add Best Performances", () => { - List plays = new List(); + List scores = new List(); Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; List selectedMods = new List(availableMods); for (int i = 0; i <= availableMods.Length; i++) { - plays.Add(new Play + scores.Add(new Score { Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), - PerformancePoints = (int)(Math.Pow(0.50, i) * 800), Accuracy = Math.Pow(0.99, i), Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), - Mods = selectedMods.ToList(), + Mods = selectedMods.ToArray(), Beatmap = new BeatmapInfo { Metadata = new BeatmapMetadata @@ -91,7 +89,7 @@ namespace osu.Desktop.VisualTests.Tests if(i < availableMods.Length) selectedMods.Remove(availableMods[i]); } - ranks.BestPlays = plays; + ranks.BestScores = scores; }); } } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs index 5b3bbff3ca..f74b6792ad 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs @@ -17,25 +17,26 @@ using System.Diagnostics; using osu.Framework.Input; using osu.Framework.Localisation; using System.Globalization; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class DrawablePlay : Container + public class DrawableScore : Container { private readonly FillFlowContainer stats; private readonly FillFlowContainer metadata; private readonly ModContainer modContainer; - private readonly Play play; + private readonly Score score; private readonly double weight; - public DrawablePlay(Play play, double weight = -1) + public DrawableScore(Score score, double weight = -1) { - this.play = play; + this.score = score; this.weight = weight; Children = new Drawable[] { - new DrawableRank(play.Rank) + new DrawableRank(score.Rank) { RelativeSizeAxes = Axes.Y, Width = 60, @@ -59,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Direction = FillDirection.Vertical, Child = new OsuSpriteText { - Text = play.Date.LocalDateTime.ToShortDateString(), + Text = score.Date.LocalDateTime.ToShortDateString(), TextSize = 11, Colour = OsuColour.Gray(0xAA), Depth = -1, @@ -80,7 +81,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private void load(OsuColour colour, LocalisationEngine locale) { stats.Add(new OsuSpriteText { - Text = play.PerformancePoints + "pp", + Text = score.PP + "pp", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 18, @@ -90,7 +91,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"weighted: {(int)(play.PerformancePoints * weight)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", + Text = $"weighted: {(int)(score.PP * weight)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, @@ -99,7 +100,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }); } stats.Add(new OsuSpriteText { - Text = "accuracy: " + play.Accuracy.ToString("0.00%"), + Text = "accuracy: " + score.Accuracy.ToString("0.00%"), Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, @@ -110,7 +111,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks metadata.Add(new LinkContainer { AutoSizeAxes = Axes.Both, - Url = $"https://osu.ppy.sh/beatmaps/{play.Beatmap.OnlineBeatmapID}", + Url = $"https://osu.ppy.sh/beatmaps/{score.Beatmap.OnlineBeatmapID}", Child = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -118,13 +119,13 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { new OsuSpriteText { - Current = locale.GetUnicodePreference($"{play.Beatmap.Metadata.TitleUnicode ?? play.Beatmap.Metadata.Title} [{play.Beatmap.Version}] ", $"{play.Beatmap.Metadata.Title ?? play.Beatmap.Metadata.TitleUnicode} [{play.Beatmap.Version}] "), + Current = locale.GetUnicodePreference($"{score.Beatmap.Metadata.TitleUnicode ?? score.Beatmap.Metadata.Title} [{score.Beatmap.Version}] ", $"{score.Beatmap.Metadata.Title ?? score.Beatmap.Metadata.TitleUnicode} [{score.Beatmap.Version}] "), TextSize = 15, Font = "Exo2.0-SemiBoldItalic", }, new OsuSpriteText { - Current = locale.GetUnicodePreference(play.Beatmap.Metadata.ArtistUnicode, play.Beatmap.Metadata.Artist), + Current = locale.GetUnicodePreference(score.Beatmap.Metadata.ArtistUnicode, score.Beatmap.Metadata.Artist), TextSize = 12, Padding = new MarginPadding { Top = 3 }, Font = "Exo2.0-RegularItalic", @@ -133,7 +134,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }, }); - foreach (Mod mod in play.Mods) + foreach (Mod mod in score.Mods) modContainer.Add(new ModIcon(mod.Icon, colour.Yellow)); } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs b/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs deleted file mode 100644 index a9cbbcbef4..0000000000 --- a/osu.Game/Overlays/Profile/Sections/Ranks/Play.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Database; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; -using System; -using System.Collections.Generic; - -namespace osu.Game.Overlays.Profile.Sections.Ranks -{ - public class Play - { - public ScoreRank Rank; - public BeatmapInfo Beatmap; - public DateTimeOffset Date; - public IEnumerable Mods; - public int PerformancePoints; - public double Accuracy; - } -} diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index f19de5356c..846f0e0e47 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; +using osu.Game.Rulesets.Scoring; using System; using System.Collections.Generic; @@ -16,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections public override string Identifier => "top_ranks"; - private readonly FillFlowContainer best, firstPlace; + private readonly FillFlowContainer best, firstPlace; public RanksSection() { @@ -27,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections Text = "Best Performance", Font = "Exo2.0-RegularItalic", }, - best = new FillFlowContainer + best = new FillFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -38,7 +39,7 @@ namespace osu.Game.Overlays.Profile.Sections Text = "First Place Ranks", Font = "Exo2.0-RegularItalic", }, - firstPlace = new FillFlowContainer + firstPlace = new FillFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -47,14 +48,14 @@ namespace osu.Game.Overlays.Profile.Sections }; } - public IEnumerable BestPlays + public IEnumerable BestScores { set { int i = 0; - foreach (Play play in value) + foreach (Score score in value) { - best.Add(new DrawablePlay(play, Math.Pow(0.95, i)) + best.Add(new DrawableScore(score, Math.Pow(0.95, i)) { RelativeSizeAxes = Axes.X, Height = 60, @@ -64,12 +65,12 @@ namespace osu.Game.Overlays.Profile.Sections } } - public IEnumerable FirstPlacePlays + public IEnumerable FirstPlaceScores { set { - foreach (Play play in value) - firstPlace.Add(new DrawablePlay(play) + foreach (Score score in value) + firstPlace.Add(new DrawableScore(score) { RelativeSizeAxes = Axes.X, Height = 60, diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 2cca0f54af..d77baaa8f3 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Scoring public double Health { get; set; } = 1; + public double PP { get; set; } + [JsonProperty(@"max_combo")] public int MaxCombo { get; set; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b63ad6a271..6888ecc220 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -99,7 +99,6 @@ - From 88f206cfe40bd9055299ce51e0eabff27d69c58c Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 00:34:16 +0200 Subject: [PATCH 04/90] rename file --- .../Sections/Ranks/{DrawablePlay.cs => DrawableScore.cs} | 0 osu.Game/osu.Game.csproj | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename osu.Game/Overlays/Profile/Sections/Ranks/{DrawablePlay.cs => DrawableScore.cs} (100%) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs similarity index 100% rename from osu.Game/Overlays/Profile/Sections/Ranks/DrawablePlay.cs rename to osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6888ecc220..859b52596f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -98,7 +98,7 @@ - + From 33ce8737cc726cbdb58eb822250ae99664e08440 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 00:47:23 +0200 Subject: [PATCH 05/90] fix merge --- osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs index 9eacde0b97..1ae6281928 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Testing; -using osu.Game.Database; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Ranks; @@ -47,6 +47,7 @@ namespace osu.Desktop.VisualTests.Tests { Rank = ScoreRank.A, Accuracy = 0.735, + PP = 666, Date = DateTimeOffset.UtcNow, Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime() }, Beatmap = new BeatmapInfo @@ -73,6 +74,7 @@ namespace osu.Desktop.VisualTests.Tests { Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), Accuracy = Math.Pow(0.99, i), + PP = Math.Pow(0.5, i) * 800, Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), Mods = selectedMods.ToArray(), Beatmap = new BeatmapInfo From c02165c82072c4f1d68a8988224dd62c2cade688 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 00:52:32 +0200 Subject: [PATCH 06/90] remove unused usings --- osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs index 1ae6281928..54e6b660f5 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -8,13 +8,11 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Sections; -using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using System; using System.Collections.Generic; -using System.Linq; namespace osu.Desktop.VisualTests.Tests { From cca49d6ed5936dea16370167d42674a9692f6a23 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 15:06:46 +0200 Subject: [PATCH 07/90] some renaming, a show more button and a placeholder if no scores exist --- .../Tests/TestCaseUserRanks.cs | 4 +- .../Overlays/Profile/Sections/RanksSection.cs | 164 +++++++++++++++--- 2 files changed, 143 insertions(+), 25 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs index 54e6b660f5..607a6b9a91 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs @@ -39,7 +39,7 @@ namespace osu.Desktop.VisualTests.Tests } }); - AddStep("Add First Place", () => ranks.FirstPlaceScores = new[] + AddStep("Add First Place", () => ranks.ScoresFirst = new[] { new Score { @@ -89,7 +89,7 @@ namespace osu.Desktop.VisualTests.Tests if(i < availableMods.Length) selectedMods.Remove(availableMods[i]); } - ranks.BestScores = scores; + ranks.ScoresBest = scores.ToArray(); }); } } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 846f0e0e47..b0f5e2080a 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -1,13 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using OpenTK.Graphics; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Scoring; using System; -using System.Collections.Generic; namespace osu.Game.Overlays.Profile.Sections { @@ -17,64 +21,178 @@ namespace osu.Game.Overlays.Profile.Sections public override string Identifier => "top_ranks"; - private readonly FillFlowContainer best, firstPlace; + private readonly ScoreFlowContainer best, first; + private readonly OsuSpriteText bestMissing, firstMissing; public RanksSection() { Children = new Drawable[] { - new OsuSpriteText { + new OsuSpriteText + { TextSize = 15, Text = "Best Performance", Font = "Exo2.0-RegularItalic", + Margin = new MarginPadding { Top = 10, Bottom = 10 }, }, - best = new FillFlowContainer + best = new ScoreFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, }, - new OsuSpriteText { + bestMissing = new OsuSpriteText + { + TextSize = 14, + Text = "No awesome performance records yet. :(", + }, + new OsuSpriteText + { TextSize = 15, Text = "First Place Ranks", Font = "Exo2.0-RegularItalic", + Margin = new MarginPadding { Top = 20, Bottom = 10 }, }, - firstPlace = new FillFlowContainer + first = new ScoreFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, + }, + firstMissing = new OsuSpriteText + { + TextSize = 14, + Text = "No awesome performance records yet. :(", }, }; } - public IEnumerable BestScores + public Score[] ScoresBest { set { - int i = 0; - foreach (Score score in value) + best.Clear(); + if (value.Length == 0) { - best.Add(new DrawableScore(score, Math.Pow(0.95, i)) - { - RelativeSizeAxes = Axes.X, - Height = 60, - }); - i++; + bestMissing.Show(); } + else + { + bestMissing.Hide(); + int i = 0; + foreach (Score score in value) + { + best.Add(new DrawableScore(score, Math.Pow(0.95, i)) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + i++; + } + } + best.ShowMore(); } } - public IEnumerable FirstPlaceScores + public Score[] ScoresFirst { set { - foreach (Score score in value) - firstPlace.Add(new DrawableScore(score) + first.Clear(); + if (value.Length == 0) + { + firstMissing.Show(); + } + else + { + firstMissing.Hide(); + foreach (Score score in value) + first.Add(new DrawableScore(score) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + } + first.ShowMore(); + } + } + + private class ScoreFlowContainer : Container + { + private readonly FillFlowContainer scores; + private readonly OsuClickableContainer showMoreText; + + protected override Container Content => scores; + + private int shownScores; + + public ScoreFlowContainer() + { + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 60, - }); + scores = new FillFlowContainer() + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + }, + showMoreText = new ShowMoreContainer + { + Action = ShowMore, + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Alpha = 0, + Child = new OsuSpriteText + { + TextSize = 14, + Text = "show more", + } + } + }, + }; + } + + public override void Clear(bool disposeChildren) + { + base.Clear(disposeChildren); + shownScores = 0; + showMoreText.Show(); + } + + public void ShowMore() + { + shownScores = Math.Min(Children.Count, shownScores + 5); + int i = 0; + foreach(DrawableScore score in Children) + score.FadeTo(i++ < shownScores ? 1 : 0); + showMoreText.FadeTo(shownScores == Children.Count ? 0 : 1); + } + + private class ShowMoreContainer : OsuClickableContainer + { + private Color4 hoverColour; + + protected override bool OnHover(InputState state) + { + this.FadeColour(hoverColour, 500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + this.FadeColour(Color4.White, 500, Easing.OutQuint); + base.OnHoverLost(state); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverColour = colours.Yellow; + } } } } From 02a22e3f774eb8e9400da1ff28ecf13ae7c1d202 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 29 Jul 2017 15:16:31 +0200 Subject: [PATCH 08/90] remove empty argument list --- osu.Game/Overlays/Profile/Sections/RanksSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index b0f5e2080a..a99aceb893 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Profile.Sections Direction = FillDirection.Vertical, Children = new Drawable[] { - scores = new FillFlowContainer() + scores = new FillFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, From 1c2329f111bf750d98baab189f58b0c3e76cde88 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Tue, 8 Aug 2017 23:11:46 +0200 Subject: [PATCH 09/90] generalize the hover code --- .../Graphics/Containers/OsuHoverContainer.cs | 32 ++++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 38 +++++++++---------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 osu.Game/Graphics/Containers/OsuHoverContainer.cs diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs new file mode 100644 index 0000000000..b4ce162086 --- /dev/null +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -0,0 +1,32 @@ + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Input; + +namespace osu.Game.Graphics.Containers +{ + + public class OsuHoverContainer : OsuClickableContainer + { + private Color4 hoverColour; + + protected override bool OnHover(InputState state) + { + this.FadeColour(hoverColour, 500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + this.FadeColour(Color4.White, 500, Easing.OutQuint); + base.OnHoverLost(state); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverColour = colours.Yellow; + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 93044315cc..891487cfa7 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using System.Diagnostics; using System.Globalization; +using System.Collections.Generic; namespace osu.Game.Overlays.Profile { @@ -509,34 +510,29 @@ namespace osu.Game.Overlays.Profile public class LinkText : OsuSpriteText { - public override bool HandleInput => Url != null; + private readonly OsuHoverContainer content; - public string Url; + public override bool HandleInput => content.Action != null; - private Color4 hoverColour; + protected override Container Content => content ?? (Container)this; - protected override bool OnHover(InputState state) + protected override IEnumerable FlowingChildren => Children; + + public string Url { - this.FadeColour(hoverColour, 500, Easing.OutQuint); - return base.OnHover(state); + set + { + if(value != null) + content.Action = () => Process.Start(value); + } } - protected override void OnHoverLost(InputState state) + public LinkText() { - this.FadeColour(Color4.White, 500, Easing.OutQuint); - base.OnHoverLost(state); - } - - protected override bool OnClick(InputState state) - { - Process.Start(Url); - return true; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverColour = colours.Yellow; + AddInternal(content = new OsuHoverContainer + { + AutoSizeAxes = Axes.Both, + }); } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8312a1a319..8cbaee3072 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -92,6 +92,7 @@ + From 9f005488f7dca56b135340419ba892862a542066 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 01:43:52 +0200 Subject: [PATCH 10/90] make it work again after merge --- .../Visual}/TestCaseUserRanks.cs | 0 osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj | 1 - osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs | 8 ++------ 4 files changed, 3 insertions(+), 7 deletions(-) rename {osu.Desktop.VisualTests/Tests => osu.Desktop.Tests/Visual}/TestCaseUserRanks.cs (100%) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs similarity index 100% rename from osu.Desktop.VisualTests/Tests/TestCaseUserRanks.cs rename to osu.Desktop.Tests/Visual/TestCaseUserRanks.cs diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index aa862498d1..9210b5eb3a 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -109,6 +109,7 @@ + diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 64fe3d4b95..8bba59207f 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -186,7 +186,6 @@ - diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index f74b6792ad..9279bd0156 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -156,25 +156,21 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Children = new[] { - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = FontAwesome.fa_osu_mod_bg, Colour = colour, Shadow = true, - TextSize = 30, - UseFullGlyphHeight = false, }, - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = icon, Colour = OsuColour.Gray(84), - TextSize = 18, Position = new Vector2(0f, 2f), - UseFullGlyphHeight = false, }, }; } From 274ebbd1f7f1ff197c8212f7ca6655fa33f7befe Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 18:45:37 +0200 Subject: [PATCH 11/90] remove duplicated code and "simplify" ShowMore logic --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 2 +- .../Profile/Sections/Ranks/DrawableScore.cs | 71 ++++--------------- .../Overlays/Profile/Sections/RanksSection.cs | 44 ++---------- 3 files changed, 19 insertions(+), 98 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs index 607a6b9a91..d8e3449b1e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs @@ -47,7 +47,7 @@ namespace osu.Desktop.VisualTests.Tests Accuracy = 0.735, PP = 666, Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime() }, + Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, Beatmap = new BeatmapInfo { Metadata = new BeatmapMetadata diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index 9279bd0156..9318798ec3 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -12,12 +12,11 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Select.Leaderboards; using System.Linq; -using OpenTK.Graphics; using System.Diagnostics; -using osu.Framework.Input; using osu.Framework.Localisation; using System.Globalization; using osu.Game.Rulesets.Scoring; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -72,7 +71,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Width = 60, - Margin = new MarginPadding{ Right = 140 } + Margin = new MarginPadding{ Right = 150 } } }; } @@ -108,10 +107,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Font = "Exo2.0-RegularItalic", }); - metadata.Add(new LinkContainer + metadata.Add(new OsuHoverContainer { AutoSizeAxes = Axes.Both, - Url = $"https://osu.ppy.sh/beatmaps/{score.Beatmap.OnlineBeatmapID}", + Action = () => Process.Start($"https://osu.ppy.sh/beatmaps/{score.Beatmap.OnlineBeatmapID}"), Child = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -135,7 +134,11 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }); foreach (Mod mod in score.Mods) - modContainer.Add(new ModIcon(mod.Icon, colour.Yellow)); + modContainer.Add(new ModIcon(mod) + { + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.5f), + }); } private class ModContainer : FlowContainer @@ -148,62 +151,14 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks } } - private class ModIcon : Container + private class ModIcon : Rulesets.UI.ModIcon, IHasTooltip { - public ModIcon(FontAwesome icon, Color4 colour) + public ModIcon(Mod mod) : base(mod) { - AutoSizeAxes = Axes.Both; - - Children = new[] - { - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = FontAwesome.fa_osu_mod_bg, - Colour = colour, - Shadow = true, - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = icon, - Colour = OsuColour.Gray(84), - Position = new Vector2(0f, 2f), - }, - }; - } - } - - private class LinkContainer : OsuClickableContainer - { - public string Url; - - private Color4 hoverColour; - - public LinkContainer() - { - Action = () => Process.Start(Url); + TooltipText = mod.Name; } - protected override bool OnHover(InputState state) - { - this.FadeColour(hoverColour, 500, Easing.OutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - this.FadeColour(Color4.White, 500, Easing.OutQuint); - base.OnHoverLost(state); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverColour = colours.Yellow; - } + public string TooltipText { get; } } } } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index a99aceb893..e9cc0bc00c 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -1,17 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Graphics; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Scoring; using System; +using System.Linq; namespace osu.Game.Overlays.Profile.Sections { @@ -84,6 +81,7 @@ namespace osu.Game.Overlays.Profile.Sections { RelativeSizeAxes = Axes.X, Height = 60, + Alpha = 0, }); i++; } @@ -109,6 +107,7 @@ namespace osu.Game.Overlays.Profile.Sections { RelativeSizeAxes = Axes.X, Height = 60, + Alpha = 0, }); } first.ShowMore(); @@ -122,8 +121,6 @@ namespace osu.Game.Overlays.Profile.Sections protected override Container Content => scores; - private int shownScores; - public ScoreFlowContainer() { InternalChild = new FillFlowContainer @@ -139,7 +136,7 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Direction = FillDirection.Vertical, }, - showMoreText = new ShowMoreContainer + showMoreText = new OsuHoverContainer { Action = ShowMore, AutoSizeAxes = Axes.Both, @@ -159,41 +156,10 @@ namespace osu.Game.Overlays.Profile.Sections public override void Clear(bool disposeChildren) { base.Clear(disposeChildren); - shownScores = 0; showMoreText.Show(); } - public void ShowMore() - { - shownScores = Math.Min(Children.Count, shownScores + 5); - int i = 0; - foreach(DrawableScore score in Children) - score.FadeTo(i++ < shownScores ? 1 : 0); - showMoreText.FadeTo(shownScores == Children.Count ? 0 : 1); - } - - private class ShowMoreContainer : OsuClickableContainer - { - private Color4 hoverColour; - - protected override bool OnHover(InputState state) - { - this.FadeColour(hoverColour, 500, Easing.OutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - this.FadeColour(Color4.White, 500, Easing.OutQuint); - base.OnHoverLost(state); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverColour = colours.Yellow; - } - } + public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = (i < 5 ? 1 : 0)) == 0).Any() ? 1 : 0; } } } From 8631c469fcc69eb4886caf69574c45495632e2af Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 18:50:44 +0200 Subject: [PATCH 12/90] add license header --- osu.Game/Graphics/Containers/OsuHoverContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index b4ce162086..efac292c76 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -1,4 +1,6 @@ - +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; From c2c9095b0235c2284ad91925f80a709a21972014 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 18:57:55 +0200 Subject: [PATCH 13/90] fix CI issues --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 - osu.Game/Overlays/Profile/Sections/RanksSection.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs index d8e3449b1e..a561559fdc 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Scoring; using System; using System.Collections.Generic; -namespace osu.Desktop.VisualTests.Tests +namespace osu.Desktop.Tests.Visual { public class TestCaseUserRanks : TestCase { diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f3e8dc5562..b6d691e549 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index e9cc0bc00c..6c3814a75f 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -159,7 +159,7 @@ namespace osu.Game.Overlays.Profile.Sections showMoreText.Show(); } - public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = (i < 5 ? 1 : 0)) == 0).Any() ? 1 : 0; + public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = i < 5 ? 1 : 0) == 0).Any() ? 1 : 0; } } } From c877a5a8b73b7c59d41038850c4d8169c0fe45ca Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 19:20:41 +0200 Subject: [PATCH 14/90] update TestCase --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 46 ++++++++++--------- .../Graphics/Containers/OsuHoverContainer.cs | 1 - .../Overlays/Profile/Sections/RanksSection.cs | 2 +- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs index a561559fdc..278f3408bf 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs @@ -39,28 +39,6 @@ namespace osu.Desktop.Tests.Visual } }); - AddStep("Add First Place", () => ranks.ScoresFirst = new[] - { - new Score - { - Rank = ScoreRank.A, - Accuracy = 0.735, - PP = 666, - Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "FREEDOM DiVE", - Artist = "xi" - }, - Version = "FOUR DIMENSIONS", - OnlineBeatmapID = 129891, - } - } - }); - AddStep("Add Best Performances", () => { List scores = new List(); @@ -91,6 +69,30 @@ namespace osu.Desktop.Tests.Visual } ranks.ScoresBest = scores.ToArray(); }); + + AddStep("Add First Place", () => ranks.ScoresFirst = new[] + { + new Score + { + Rank = ScoreRank.A, + Accuracy = 0.735, + PP = 666, + Date = DateTimeOffset.UtcNow, + Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "FREEDOM DiVE", + Artist = "xi" + }, + Version = "FOUR DIMENSIONS", + OnlineBeatmapID = 129891, + } + } + }); + + AddStep("Show More", ((RanksSection.ScoreFlowContainer)ranks.Children[1]).ShowMore); } } } diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index efac292c76..3f82ad2179 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -8,7 +8,6 @@ using osu.Framework.Input; namespace osu.Game.Graphics.Containers { - public class OsuHoverContainer : OsuClickableContainer { private Color4 hoverColour; diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 6c3814a75f..e7c32f76e4 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -114,7 +114,7 @@ namespace osu.Game.Overlays.Profile.Sections } } - private class ScoreFlowContainer : Container + public class ScoreFlowContainer : Container { private readonly FillFlowContainer scores; private readonly OsuClickableContainer showMoreText; From bb8374b4fef83d7b98df2d6e11f407d9c87ce78a Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 19:47:51 +0200 Subject: [PATCH 15/90] override LoadComplete instead of using the constructor --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs index 278f3408bf..867e62859d 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs @@ -20,8 +20,9 @@ namespace osu.Desktop.Tests.Visual { public override string Description => "showing your latest achievements"; - public TestCaseUserRanks() + protected override void LoadComplete() { + base.LoadComplete(); RanksSection ranks; Add(new Container From acc9b20b0f32ade24a06b62438f275820ddde69c Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 22:37:05 +0200 Subject: [PATCH 16/90] move another thing to LoadComplete instead of the constructor --- osu.Game/Overlays/Profile/Sections/RanksSection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index e7c32f76e4..2d8da5b1f0 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -116,12 +116,12 @@ namespace osu.Game.Overlays.Profile.Sections public class ScoreFlowContainer : Container { - private readonly FillFlowContainer scores; - private readonly OsuClickableContainer showMoreText; + private FillFlowContainer scores; + private OsuClickableContainer showMoreText; protected override Container Content => scores; - public ScoreFlowContainer() + protected override void LoadComplete() { InternalChild = new FillFlowContainer { From 15e4e487e2aa1ee321ac855adbc5b7820f9271c2 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Wed, 9 Aug 2017 22:58:06 +0200 Subject: [PATCH 17/90] I hope this works --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 3 +- .../Overlays/Profile/Sections/RanksSection.cs | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs index 867e62859d..41f3a37e94 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs @@ -16,13 +16,14 @@ using System.Collections.Generic; namespace osu.Desktop.Tests.Visual { - public class TestCaseUserRanks : TestCase + internal class TestCaseUserRanks : TestCase { public override string Description => "showing your latest achievements"; protected override void LoadComplete() { base.LoadComplete(); + RanksSection ranks; Add(new Container diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 2d8da5b1f0..f6590140ec 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -136,19 +136,6 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Direction = FillDirection.Vertical, }, - showMoreText = new OsuHoverContainer - { - Action = ShowMore, - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Alpha = 0, - Child = new OsuSpriteText - { - TextSize = 14, - Text = "show more", - } - } }, }; } @@ -156,7 +143,21 @@ namespace osu.Game.Overlays.Profile.Sections public override void Clear(bool disposeChildren) { base.Clear(disposeChildren); - showMoreText.Show(); + if (showMoreText == null) + ((FillFlowContainer)InternalChild).Add(showMoreText = new OsuHoverContainer + { + Action = ShowMore, + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Child = new OsuSpriteText + { + TextSize = 14, + Text = "show more", + } + }); + else + showMoreText.Show(); } public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = i < 5 ? 1 : 0) == 0).Any() ? 1 : 0; From 98b847b025ce1c9e8199c1635dce6ece2efd7905 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 20:05:43 +0900 Subject: [PATCH 18/90] Add API retrieval support --- .../Online/API/Requests/GetScoresRequest.cs | 23 ++++++- .../API/Requests/GetUserScoresRequest.cs | 28 +++++++++ osu.Game/Overlays/Profile/ProfileSection.cs | 10 +++ .../Profile/Sections/Ranks/DrawableScore.cs | 14 +++-- .../Overlays/Profile/Sections/RanksSection.cs | 62 +++++++++++++++++-- osu.Game/Overlays/UserProfileOverlay.cs | 2 + osu.Game/Rulesets/Scoring/Score.cs | 4 +- osu.Game/osu.Game.csproj | 1 + 8 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetUserScoresRequest.cs diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index ef9ee85d25..dfe1310325 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -7,6 +7,7 @@ using System.Linq; using Newtonsoft.Json; using osu.Framework.IO.Network; using osu.Game.Beatmaps; +using osu.Game.Rulesets; using osu.Game.Users; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; @@ -73,6 +74,9 @@ namespace osu.Game.Online.API.Requests set { Replay = value; } } + [JsonProperty(@"mode_int")] + public int OnlineRulesetID { get; set; } + [JsonProperty(@"score_id")] private long onlineScoreID { @@ -85,6 +89,18 @@ namespace osu.Game.Online.API.Requests set { Date = value; } } + [JsonProperty(@"beatmap")] + private BeatmapInfo beatmap + { + set { Beatmap = value; } + } + + [JsonProperty(@"beatmapset")] + private BeatmapMetadata metadata + { + set { Beatmap.Metadata = value; } + } + [JsonProperty(@"statistics")] private Dictionary jsonStats { @@ -122,7 +138,12 @@ namespace osu.Game.Online.API.Requests public void ApplyBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; - Ruleset = beatmap.Ruleset; + ApplyRuleset(beatmap.Ruleset); + } + + public void ApplyRuleset(RulesetInfo ruleset) + { + Ruleset = ruleset; // Evaluate the mod string Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs new file mode 100644 index 0000000000..20597aecc1 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; + +namespace osu.Game.Online.API.Requests +{ + public class GetUserScoresRequest : APIRequest> + { + private readonly long userId; + private readonly ScoreType type; + + public GetUserScoresRequest(long userId, ScoreType type) + { + this.userId = userId; + this.type = type; + } + + protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}"; + } + + public enum ScoreType + { + Best, + Firsts, + Recent + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 2b5084e321..df7c0e117f 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Users; using OpenTK.Graphics; namespace osu.Game.Overlays.Profile @@ -18,8 +19,17 @@ namespace osu.Game.Overlays.Profile public abstract string Identifier { get; } private readonly FillFlowContainer content; + protected override Container Content => content; + public virtual User User + { + get { return user; } + set { user = value; } + } + + private User user; + protected ProfileSection() { Direction = FillDirection.Vertical; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index 9318798ec3..d92ebf6dca 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -79,26 +79,28 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load(OsuColour colour, LocalisationEngine locale) { - stats.Add(new OsuSpriteText { - Text = score.PP + "pp", + stats.Add(new OsuSpriteText + { + Text = $"{score.PP ?? 0}pp", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 18, Font = "Exo2.0-BoldItalic", }); - if(weight != -1) + if (weight != -1) { stats.Add(new OsuSpriteText { - Text = $"weighted: {(int)(score.PP * weight)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", + Text = $"weighted: {(int)(score?.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, TextSize = 11, Font = "Exo2.0-RegularItalic", - }); + }); } - stats.Add(new OsuSpriteText { + stats.Add(new OsuSpriteText + { Text = "accuracy: " + score.Accuracy.ToString("0.00%"), Anchor = Anchor.TopRight, Origin = Anchor.TopRight, diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index f6590140ec..4f9470bd6e 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -8,7 +8,13 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Scoring; using System; +using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Rulesets; +using osu.Game.Users; namespace osu.Game.Overlays.Profile.Sections { @@ -21,6 +27,9 @@ namespace osu.Game.Overlays.Profile.Sections private readonly ScoreFlowContainer best, first; private readonly OsuSpriteText bestMissing, firstMissing; + private APIAccess api; + private RulesetStore rulesets; + public RanksSection() { Children = new Drawable[] @@ -62,12 +71,57 @@ namespace osu.Game.Overlays.Profile.Sections }; } - public Score[] ScoresBest + [BackgroundDependencyLoader] + private void load(APIAccess api, RulesetStore rulesets) + { + this.api = api; + this.rulesets = rulesets; + } + + public override User User + { + get + { + return base.User; + } + + set + { + base.User = value; + + // fetch online ranks + foreach (ScoreType m in new[] { ScoreType.Best, ScoreType.Firsts }) + { + ScoreType thisType = m; + var req = new GetUserScoresRequest(User.Id, m); + req.Success += scores => + { + foreach (var s in scores) + s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID)); + + switch (thisType) + { + case ScoreType.Best: + ScoresBest = scores; + break; + case ScoreType.Firsts: + ScoresFirst = scores; + break; + } + }; + + Schedule(() => { api.Queue(req); }); + } + } + } + + + public IEnumerable ScoresBest { set { best.Clear(); - if (value.Length == 0) + if (!value.Any()) { bestMissing.Show(); } @@ -90,12 +144,12 @@ namespace osu.Game.Overlays.Profile.Sections } } - public Score[] ScoresFirst + public IEnumerable ScoresFirst { set { first.Clear(); - if (value.Length == 0) + if (!value.Any()) { firstMissing.Show(); } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f03ef3f1ed..034d956366 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -174,6 +174,8 @@ namespace osu.Game.Overlays var sec = sections.FirstOrDefault(s => s.Identifier == id); if (sec != null) { + sec.User = user; + sectionsContainer.Add(sec); tabs.AddItem(sec); } diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 69ed9197d7..2af6509f09 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Scoring public double Health { get; set; } = 1; - public double PP { get; set; } + public double? PP { get; set; } public int MaxCombo { get; set; } @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Scoring public RulesetInfo Ruleset { get; set; } - public Mod[] Mods { get; set; } + public Mod[] Mods { get; set; } = { }; public User User; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4046c0f9a1..a18087b856 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -81,6 +81,7 @@ + From be1e868a2a6570a8c33dc7643c89280e13fd2f9c Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sun, 17 Sep 2017 22:39:34 +0200 Subject: [PATCH 19/90] add previews to osu!direct --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 34 +++++++ osu.Game/Overlays/Direct/DirectListPanel.cs | 83 +++++++++++++--- osu.Game/Overlays/Direct/DirectPanel.cs | 7 ++ osu.Game/Overlays/Direct/PlayButton.cs | 105 ++++++++++++++++++++ osu.Game/Overlays/DirectOverlay.cs | 18 ++++ osu.Game/osu.Game.csproj | 1 + 6 files changed, 232 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Overlays/Direct/PlayButton.cs diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 3a9e75bd38..b638e21c4b 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -13,6 +13,8 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Input; +using osu.Framework.Audio; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { @@ -22,6 +24,11 @@ namespace osu.Game.Overlays.Direct private const float vertical_padding = 5; private FillFlowContainer bottomPanel; + private PlayButton playButton; + private Box progressBar; + + protected override PlayButton PlayButton => playButton; + public override Bindable PreviewPlaying { get; } = new Bindable(); public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { @@ -88,6 +95,15 @@ namespace osu.Game.Overlays.Direct { RelativeSizeAxes = Axes.Both, }, + progressBar = new Box + { + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + BypassAutoSizeAxes = Axes.Both, + Size = new Vector2(0, 3), + Alpha = 0, + Colour = colours.Yellow, + }, new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -170,7 +186,25 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, + playButton = new PlayButton(PreviewPlaying) + { + Margin = new MarginPadding { Top = 5, Left = 10 }, + Size = new Vector2(30), + Alpha = 0, + TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + }, }); + + PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && playButton.Track != null) + progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } protected override bool OnClick(InputState state) diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index b3502b0827..7f233f2113 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -15,6 +15,8 @@ using osu.Framework.Input; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Framework.Configuration; +using osu.Framework.Audio; namespace osu.Game.Overlays.Direct { @@ -30,8 +32,14 @@ namespace osu.Game.Overlays.Direct Height = height; } + private PlayButton playButton; + private Box progressBar; + + protected override PlayButton PlayButton => playButton; + public override Bindable PreviewPlaying { get; } = new Bindable(); + [BackgroundDependencyLoader] - private void load(LocalisationEngine localisation) + private void load(LocalisationEngine localisation, OsuColour colours) { Content.CornerRadius = 5; @@ -50,29 +58,51 @@ namespace osu.Game.Overlays.Direct { new FillFlowContainer { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, + Direction = FillDirection.Horizontal, + LayoutEasing = Easing.OutQuint, + LayoutDuration = 120, + Spacing = new Vector2(10, 0), Children = new Drawable[] { - new OsuSpriteText + playButton = new PlayButton(PreviewPlaying) { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), - TextSize = 18, - Font = @"Exo2.0-BoldItalic", - }, - new OsuSpriteText - { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), - Font = @"Exo2.0-BoldItalic", + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Size = new Vector2(height / 2), + FillMode = FillMode.Fit, + Alpha = 0, + TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { - AutoSizeAxes = Axes.X, - Height = 20, - Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, - Children = GetDifficultyIcons(), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), + TextSize = 18, + Font = @"Exo2.0-BoldItalic", + }, + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), + Font = @"Exo2.0-BoldItalic", + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.X, + Height = 20, + Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, + Children = GetDifficultyIcons(), + }, + }, }, - }, + } }, new FillFlowContainer { @@ -128,7 +158,28 @@ namespace osu.Game.Overlays.Direct }, }, }, + progressBar = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + BypassAutoSizeAxes = Axes.Y, + Size = new Vector2(0, 3), + Alpha = 0, + Colour = colours.Yellow, + }, }); + + PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && playButton.Track != null) + progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } private class DownloadButton : OsuClickableContainer diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 6f1f581d0b..24cd8dc54e 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -20,6 +20,7 @@ using osu.Game.Online.API; using osu.Framework.Logging; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { @@ -38,6 +39,9 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; + public abstract Bindable PreviewPlaying { get; } + protected abstract PlayButton PlayButton { get; } + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -106,6 +110,7 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + PlayButton.FadeIn(120, Easing.InOutQuint); return base.OnHover(state); } @@ -114,6 +119,8 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); content.MoveToY(0, hover_transition_time, Easing.OutQuint); + if (!PreviewPlaying) + PlayButton.FadeOut(120, Easing.InOutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs new file mode 100644 index 0000000000..8cfe1a30cb --- /dev/null +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -0,0 +1,105 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using System.Threading.Tasks; + +namespace osu.Game.Overlays.Direct +{ + public class PlayButton : Container + { + public string TrackURL; + + public Bindable Playing; + + public Track Track; + private Bindable gameBeatmap; + private AudioManager audio; + + private Color4 hoverColour; + private readonly SpriteIcon icon; + + public PlayButton(Bindable playing) + { + Playing = playing; + Add(icon = new SpriteIcon() + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.fa_play, + }); + + Playing.ValueChanged += newValue => icon.Icon = newValue ? (Track == null ? FontAwesome.fa_spinner : FontAwesome.fa_pause) : FontAwesome.fa_play; + + Playing.ValueChanged += newValue => + { + if (newValue) + Track?.Start(); + else + Track?.Stop(); + }; + + Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour, OsuGameBase game, AudioManager audio) + { + hoverColour = colour.Yellow; + gameBeatmap = game.Beatmap; + this.audio = audio; + } + + private Task loadTask; + + protected override bool OnClick(InputState state) + { + gameBeatmap.Value.Track.Stop(); + + Playing.Value = !Playing.Value; + + if (loadTask == null) + { + icon.Spin(2000, RotationDirection.Clockwise); + + loadTask = Task.Run(() => + { + Track = audio.Track.Get(TrackURL); + Track.Looping = true; + if (Playing) + Track.Start(); + + icon.ClearTransforms(); + icon.Rotation = 0; + Playing.TriggerChange(); + }); + } + + return true; + } + + protected override bool OnHover(InputState state) + { + icon.FadeColour(hoverColour, 120, Easing.InOutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if(!Playing) + icon.FadeColour(Color4.White, 120, Easing.InOutQuint); + base.OnHoverLost(state); + } + } +} diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9c07e1087f..9bb2afe127 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -32,6 +32,7 @@ namespace osu.Game.Overlays private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; private FillFlowContainer panels; + private DirectPanel playing; protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); @@ -201,6 +202,12 @@ namespace osu.Game.Overlays panels.FadeOut(200); panels.Expire(); panels = null; + + if (playing != null) + { + playing.PreviewPlaying.Value = false; + playing = null; + } } if (BeatmapSets == null) return; @@ -223,6 +230,17 @@ namespace osu.Game.Overlays }) }; + foreach (DirectPanel panel in newPanels.Children) + panel.PreviewPlaying.ValueChanged += newValue => + { + if (newValue) + { + if (playing != null && playing != panel) + playing.PreviewPlaying.Value = false; + playing = panel; + } + }; + LoadComponentAsync(newPanels, p => { if (panels != null) ScrollFlow.Remove(panels); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 65ec7d31b3..f75db14f52 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -105,6 +105,7 @@ + From 3e8ae93b340093b89724ecc34c95e2e0a9676929 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sun, 17 Sep 2017 22:54:23 +0200 Subject: [PATCH 20/90] appveyor --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +-- osu.Game/Overlays/Direct/DirectListPanel.cs | 3 +-- osu.Game/Overlays/Direct/PlayButton.cs | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index b638e21c4b..24ccd8b7eb 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Input; -using osu.Framework.Audio; using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct @@ -191,7 +190,7 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), Alpha = 0, - TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, }); diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7f233f2113..7112e927bd 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -16,7 +16,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Framework.Configuration; -using osu.Framework.Audio; namespace osu.Game.Overlays.Direct { @@ -74,7 +73,7 @@ namespace osu.Game.Overlays.Direct Size = new Vector2(height / 2), FillMode = FillMode.Fit, Alpha = 0, - TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 8cfe1a30cb..b0d011a81c 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - public string TrackURL; + public string TrackUrl; public Bindable Playing; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(Bindable playing) { Playing = playing; - Add(icon = new SpriteIcon() + Add(icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Direct loadTask = Task.Run(() => { - Track = audio.Track.Get(TrackURL); + Track = audio.Track.Get(TrackUrl); Track.Looping = true; if (Playing) Track.Start(); From 72141935e84f8edd224c94224d1d18f917ff123d Mon Sep 17 00:00:00 2001 From: Jorolf Date: Thu, 21 Sep 2017 22:07:23 +0200 Subject: [PATCH 21/90] make pagination work and remove duplication in RanksSection --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 100 -------- osu.Game/Beatmaps/BeatmapInfo.cs | 2 + .../API/Requests/GetUserScoresRequest.cs | 6 +- .../Profile/Sections/Ranks/DrawableScore.cs | 5 +- .../Overlays/Profile/Sections/RanksSection.cs | 236 ++++++++---------- osu.Game/Tests/Visual/TestCaseUserRanks.cs | 75 +----- osu.Game/osu.Game.csproj | 2 - 7 files changed, 121 insertions(+), 305 deletions(-) delete mode 100644 osu.Desktop.Tests/Visual/TestCaseUserRanks.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs deleted file mode 100644 index 41f3a37e94..0000000000 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ /dev/null @@ -1,100 +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.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Overlays.Profile.Sections; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Scoring; -using System; -using System.Collections.Generic; - -namespace osu.Desktop.Tests.Visual -{ - internal class TestCaseUserRanks : TestCase - { - public override string Description => "showing your latest achievements"; - - protected override void LoadComplete() - { - base.LoadComplete(); - - RanksSection ranks; - - Add(new Container - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.2f) - }, - ranks = new RanksSection(), - } - }); - - AddStep("Add Best Performances", () => - { - List scores = new List(); - Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; - List selectedMods = new List(availableMods); - for (int i = 0; i <= availableMods.Length; i++) - { - scores.Add(new Score - { - Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), - Accuracy = Math.Pow(0.99, i), - PP = Math.Pow(0.5, i) * 800, - Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), - Mods = selectedMods.ToArray(), - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "Highscore", - Artist = "Panda Eyes & Teminite" - }, - Version = "Game Over", - OnlineBeatmapID = 736215, - } - }); - if(i < availableMods.Length) - selectedMods.Remove(availableMods[i]); - } - ranks.ScoresBest = scores.ToArray(); - }); - - AddStep("Add First Place", () => ranks.ScoresFirst = new[] - { - new Score - { - Rank = ScoreRank.A, - Accuracy = 0.735, - PP = 666, - Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "FREEDOM DiVE", - Artist = "xi" - }, - Version = "FOUR DIMENSIONS", - OnlineBeatmapID = 129891, - } - } - }); - - AddStep("Show More", ((RanksSection.ScoreFlowContainer)ranks.Children[1]).ShowMore); - } - } -} diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 0776669811..5775299ffb 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -19,8 +19,10 @@ namespace osu.Game.Beatmaps //TODO: should be in database public int BeatmapVersion; + [JsonProperty("id")] public int? OnlineBeatmapID { get; set; } + [JsonProperty("beatmapset_id")] public int? OnlineBeatmapSetID { get; set; } [ForeignKey(typeof(BeatmapSetInfo))] diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs index 20597aecc1..98db234196 100644 --- a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -9,14 +9,16 @@ namespace osu.Game.Online.API.Requests { private readonly long userId; private readonly ScoreType type; + private readonly int offset; - public GetUserScoresRequest(long userId, ScoreType type) + public GetUserScoresRequest(long userId, ScoreType type, int offset = 0) { this.userId = userId; this.type = type; + this.offset = offset; } - protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}"; + protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}?offset={offset}"; } public enum ScoreType diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index d92ebf6dca..27df3fd0fa 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -17,6 +17,7 @@ using osu.Framework.Localisation; using System.Globalization; using osu.Game.Rulesets.Scoring; using osu.Framework.Graphics.Cursor; +using System; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -81,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"{score.PP ?? 0}pp", + Text = $"{Math.Round(score.PP ?? 0)}pp", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 18, @@ -91,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"weighted: {(int)(score?.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", + Text = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 4f9470bd6e..b6c56f5cb1 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -15,6 +15,8 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Users; +using osu.Game.Graphics.UserInterface; +using OpenTK; namespace osu.Game.Overlays.Profile.Sections { @@ -24,8 +26,7 @@ namespace osu.Game.Overlays.Profile.Sections public override string Identifier => "top_ranks"; - private readonly ScoreFlowContainer best, first; - private readonly OsuSpriteText bestMissing, firstMissing; + private readonly ScoreContainer best, first; private APIAccess api; private RulesetStore rulesets; @@ -34,40 +35,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new OsuSpriteText - { - TextSize = 15, - Text = "Best Performance", - Font = "Exo2.0-RegularItalic", - Margin = new MarginPadding { Top = 10, Bottom = 10 }, - }, - best = new ScoreFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }, - bestMissing = new OsuSpriteText - { - TextSize = 14, - Text = "No awesome performance records yet. :(", - }, - new OsuSpriteText - { - TextSize = 15, - Text = "First Place Ranks", - Font = "Exo2.0-RegularItalic", - Margin = new MarginPadding { Top = 20, Bottom = 10 }, - }, - first = new ScoreFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }, - firstMissing = new OsuSpriteText - { - TextSize = 14, - Text = "No awesome performance records yet. :(", - }, + best = new ScoreContainer(ScoreType.Best, "Best Performance", true), + first = new ScoreContainer(ScoreType.Firsts, "First Place Ranks"), }; } @@ -88,119 +57,67 @@ namespace osu.Game.Overlays.Profile.Sections set { base.User = value; - - // fetch online ranks - foreach (ScoreType m in new[] { ScoreType.Best, ScoreType.Firsts }) - { - ScoreType thisType = m; - var req = new GetUserScoresRequest(User.Id, m); - req.Success += scores => - { - foreach (var s in scores) - s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID)); - - switch (thisType) - { - case ScoreType.Best: - ScoresBest = scores; - break; - case ScoreType.Firsts: - ScoresFirst = scores; - break; - } - }; - - Schedule(() => { api.Queue(req); }); - } + best.User = value; + first.User = value; } } - - public IEnumerable ScoresBest + private class ScoreContainer : FillFlowContainer { - set + private readonly FillFlowContainer scoreContainer; + private readonly OsuSpriteText missing; + private readonly OsuHoverContainer showMoreButton; + private readonly LoadingAnimation showMoreLoading; + + private ScoreType type; + private int visiblePages; + private User user; + private readonly bool includeWeigth; + + private RulesetStore rulesets; + private APIAccess api; + + public User User { - best.Clear(); - if (!value.Any()) + set { - bestMissing.Show(); + user = value; + visiblePages = 0; + scoreContainer.Clear(); + showMoreButton.Hide(); + missing.Show(); + showMore(); } - else - { - bestMissing.Hide(); - int i = 0; - foreach (Score score in value) - { - best.Add(new DrawableScore(score, Math.Pow(0.95, i)) - { - RelativeSizeAxes = Axes.X, - Height = 60, - Alpha = 0, - }); - i++; - } - } - best.ShowMore(); } - } - public IEnumerable ScoresFirst - { - set + public ScoreContainer(ScoreType type, string header, bool includeWeigth = false) { - first.Clear(); - if (!value.Any()) - { - firstMissing.Show(); - } - else - { - firstMissing.Hide(); - foreach (Score score in value) - first.Add(new DrawableScore(score) - { - RelativeSizeAxes = Axes.X, - Height = 60, - Alpha = 0, - }); - } - first.ShowMore(); - } - } + this.type = type; + this.includeWeigth = includeWeigth; - public class ScoreFlowContainer : Container - { - private FillFlowContainer scores; - private OsuClickableContainer showMoreText; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; - protected override Container Content => scores; - - protected override void LoadComplete() - { - InternalChild = new FillFlowContainer + Children = new Drawable[] { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new OsuSpriteText { - scores = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - }, + TextSize = 15, + Text = header, + Font = "Exo2.0-RegularItalic", + Margin = new MarginPadding { Top = 10, Bottom = 10 }, }, - }; - } - - public override void Clear(bool disposeChildren) - { - base.Clear(disposeChildren); - if (showMoreText == null) - ((FillFlowContainer)InternalChild).Add(showMoreText = new OsuHoverContainer + scoreContainer = new FillFlowContainer { - Action = ShowMore, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + }, + showMoreButton = new OsuHoverContainer + { + Alpha = 0, + Action = showMore, AutoSizeAxes = Axes.Both, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -209,12 +126,57 @@ namespace osu.Game.Overlays.Profile.Sections TextSize = 14, Text = "show more", } - }); - else - showMoreText.Show(); + }, + showMoreLoading = new LoadingAnimation + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Size = new Vector2(14), + }, + missing = new OsuSpriteText + { + TextSize = 14, + Text = "No awesome performance records yet. :(", + }, + }; } - public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = i < 5 ? 1 : 0) == 0).Any() ? 1 : 0; + [BackgroundDependencyLoader] + private void load(APIAccess api, RulesetStore rulesets) + { + this.api = api; + this.rulesets = rulesets; + } + + private void showMore() + { + var req = new GetUserScoresRequest(user.Id, type, visiblePages++ * 5); + + showMoreLoading.Show(); + showMoreButton.Hide(); + + req.Success += scores => + { + foreach (var s in scores) + s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID)); + + showMoreButton.FadeTo(scores.Count == 5 ? 1 : 0); + showMoreLoading.Hide(); + + if (scores.Any()) + { + missing.Hide(); + foreach (Score score in scores) + scoreContainer.Add(new DrawableScore(score, includeWeigth ? Math.Pow(0.95, scoreContainer.Count) : -1) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + } + }; + + Schedule(() => { api.Queue(req); }); + } } } } diff --git a/osu.Game/Tests/Visual/TestCaseUserRanks.cs b/osu.Game/Tests/Visual/TestCaseUserRanks.cs index 41f3a37e94..e164426a4e 100644 --- a/osu.Game/Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Game/Tests/Visual/TestCaseUserRanks.cs @@ -8,28 +8,28 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Users; using System; using System.Collections.Generic; -namespace osu.Desktop.Tests.Visual +namespace osu.Game.Tests.Visual { - internal class TestCaseUserRanks : TestCase + internal class TestCaseUserRanks : OsuTestCase { public override string Description => "showing your latest achievements"; - protected override void LoadComplete() - { - base.LoadComplete(); + public override IReadOnlyList RequiredTypes => new Type[] { typeof(DrawableScore), typeof(RanksSection) }; + public TestCaseUserRanks() + { RanksSection ranks; Add(new Container { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { new Box @@ -37,64 +37,15 @@ namespace osu.Desktop.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(0.2f) }, - ranks = new RanksSection(), - } - }); - - AddStep("Add Best Performances", () => - { - List scores = new List(); - Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; - List selectedMods = new List(availableMods); - for (int i = 0; i <= availableMods.Length; i++) - { - scores.Add(new Score + new ScrollContainer { - Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), - Accuracy = Math.Pow(0.99, i), - PP = Math.Pow(0.5, i) * 800, - Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), - Mods = selectedMods.ToArray(), - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "Highscore", - Artist = "Panda Eyes & Teminite" - }, - Version = "Game Over", - OnlineBeatmapID = 736215, - } - }); - if(i < availableMods.Length) - selectedMods.Remove(availableMods[i]); - } - ranks.ScoresBest = scores.ToArray(); - }); - - AddStep("Add First Place", () => ranks.ScoresFirst = new[] - { - new Score - { - Rank = ScoreRank.A, - Accuracy = 0.735, - PP = 666, - Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "FREEDOM DiVE", - Artist = "xi" - }, - Version = "FOUR DIMENSIONS", - OnlineBeatmapID = 129891, - } + RelativeSizeAxes = Axes.Both, + Child = ranks = new RanksSection(), + }, } }); - AddStep("Show More", ((RanksSection.ScoreFlowContainer)ranks.Children[1]).ShowMore); + AddStep("Show cookiezi", () => ranks.User = new User { Id = 124493 }); } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7a78ed8dd4..a20a5ee13f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -298,7 +298,6 @@ - @@ -318,7 +317,6 @@ - From 14b8e9fd775914861f1f48c8ced7f71d63876797 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Thu, 21 Sep 2017 22:15:42 +0200 Subject: [PATCH 22/90] remove some redundant stuff --- .../Overlays/Profile/Sections/RanksSection.cs | 17 +++-------------- osu.Game/Tests/Visual/TestCaseUserRanks.cs | 6 +----- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index b6c56f5cb1..d5ee379a5b 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -8,15 +8,14 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Scoring; using System; -using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Users; using osu.Game.Graphics.UserInterface; using OpenTK; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Profile.Sections { @@ -28,9 +27,6 @@ namespace osu.Game.Overlays.Profile.Sections private readonly ScoreContainer best, first; - private APIAccess api; - private RulesetStore rulesets; - public RanksSection() { Children = new Drawable[] @@ -40,13 +36,6 @@ namespace osu.Game.Overlays.Profile.Sections }; } - [BackgroundDependencyLoader] - private void load(APIAccess api, RulesetStore rulesets) - { - this.api = api; - this.rulesets = rulesets; - } - public override User User { get @@ -69,7 +58,7 @@ namespace osu.Game.Overlays.Profile.Sections private readonly OsuHoverContainer showMoreButton; private readonly LoadingAnimation showMoreLoading; - private ScoreType type; + private readonly ScoreType type; private int visiblePages; private User user; private readonly bool includeWeigth; @@ -166,7 +155,7 @@ namespace osu.Game.Overlays.Profile.Sections if (scores.Any()) { missing.Hide(); - foreach (Score score in scores) + foreach (OnlineScore score in scores) scoreContainer.Add(new DrawableScore(score, includeWeigth ? Math.Pow(0.95, scoreContainer.Count) : -1) { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Tests/Visual/TestCaseUserRanks.cs b/osu.Game/Tests/Visual/TestCaseUserRanks.cs index e164426a4e..9667897a7d 100644 --- a/osu.Game/Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Game/Tests/Visual/TestCaseUserRanks.cs @@ -4,13 +4,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Ranks; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; using osu.Game.Users; using System; using System.Collections.Generic; @@ -21,7 +17,7 @@ namespace osu.Game.Tests.Visual { public override string Description => "showing your latest achievements"; - public override IReadOnlyList RequiredTypes => new Type[] { typeof(DrawableScore), typeof(RanksSection) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(DrawableScore), typeof(RanksSection) }; public TestCaseUserRanks() { From 9ee824ee6661dffaf01396f47f43d270b8d8fc28 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Thu, 21 Sep 2017 22:28:15 +0200 Subject: [PATCH 23/90] some more unused stuff --- osu.Game/Overlays/Profile/Sections/RanksSection.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index d5ee379a5b..d7df239003 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Sections.Ranks; -using osu.Game.Rulesets.Scoring; using System; using System.Linq; using osu.Game.Online.API; From 1f2a82b7ab3b3dba01bf1a44e3fe5e4b15e31db8 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Tue, 26 Sep 2017 12:21:00 +0200 Subject: [PATCH 24/90] make PreviewPlaying readonly instead of abstract --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 1 - osu.Game/Overlays/Direct/DirectListPanel.cs | 1 - osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 24ccd8b7eb..3c51235fad 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -27,7 +27,6 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; - public override Bindable PreviewPlaying { get; } = new Bindable(); public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7112e927bd..3aa8c8a7c2 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; - public override Bindable PreviewPlaying { get; } = new Bindable(); [BackgroundDependencyLoader] private void load(LocalisationEngine localisation, OsuColour colours) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 24cd8dc54e..65808c32a1 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; - public abstract Bindable PreviewPlaying { get; } + public readonly Bindable PreviewPlaying = new Bindable(); protected abstract PlayButton PlayButton { get; } protected override Container Content => content; From 647304c14bd1b247c6ac1df2dce51bcb3339e0ca Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:08:30 +0200 Subject: [PATCH 25/90] move logic to DirectPanel and reuse stuff for the PreviewButton --- osu.Game/Audio/AudioLoadWrapper.cs | 35 +++++ osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 128 +++++------------- osu.Game/Overlays/Direct/DirectGridPanel.cs | 13 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 14 +- osu.Game/Overlays/Direct/DirectPanel.cs | 53 ++++++++ osu.Game/Overlays/Direct/PlayButton.cs | 91 ++++++------- osu.Game/osu.Game.csproj | 1 + 7 files changed, 166 insertions(+), 169 deletions(-) create mode 100644 osu.Game/Audio/AudioLoadWrapper.cs diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs new file mode 100644 index 0000000000..8c013cf70f --- /dev/null +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -0,0 +1,35 @@ +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Audio +{ + public class AudioLoadWrapper : Drawable + { + private readonly string preview; + + public Track Preview; + + public AudioLoadWrapper(string preview) + { + this.preview = preview; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + if (!string.IsNullOrEmpty(preview)) + { + Preview = audio.Track.Get(preview); + Preview.Volume.Value = 0.5; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index bdb06106f0..9bb8b9a1a5 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -15,6 +15,9 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; +using osu.Game.Audio; +using osu.Game.Overlays.Direct; +using osu.Framework.Configuration; namespace osu.Game.Overlays.BeatmapSet { @@ -24,27 +27,10 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Container audioWrapper; private readonly Box bg, progress; - private readonly SpriteIcon icon; - private readonly LoadingAnimation loadingAnimation; + private readonly PlayButton playButton; private Track preview; - - private bool loading - { - set - { - if (value) - { - loadingAnimation.Show(); - icon.FadeOut(transition_duration * 5, Easing.OutQuint); - } - else - { - loadingAnimation.Hide(); - icon.FadeIn(transition_duration, Easing.OutQuint); - } - } - } + private readonly Bindable playing = new Bindable(); private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet @@ -55,42 +41,11 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - Playing = false; + playing.Value = false; preview = null; } } - private bool playing; - public bool Playing - { - get { return playing; } - set - { - if (value == playing) return; - playing = value; - - if (preview == null) - { - loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet) - { - OnLoadComplete = d => - { - loading = false; - - preview = (d as AudioLoadWrapper)?.Preview; - Playing = Playing; - updatePlayingState(); - }, - }); - - return; - } - - updatePlayingState(); - } - } - public PreviewButton() { Height = 42; @@ -116,22 +71,16 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - icon = new SpriteIcon + playButton = new PlayButton(playing) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.fa_play, Size = new Vector2(18), - Shadow = false, - }, - loadingAnimation = new LoadingAnimation - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, }, }; - Action = () => Playing = !Playing; + Action = () => playing.Value = !playing.Value; + playing.ValueChanged += updatePlayingState; } [BackgroundDependencyLoader] @@ -144,12 +93,12 @@ namespace osu.Game.Overlays.BeatmapSet { base.Update(); - if (Playing && preview != null) + if (playing.Value && preview != null) { progress.Width = (float)(preview.CurrentTime / preview.Length); if (preview.HasCompleted) { - Playing = false; + playing.Value = false; preview = null; } } @@ -157,7 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet protected override void Dispose(bool isDisposing) { - Playing = false; + playing.Value = false; base.Dispose(isDisposing); } @@ -173,44 +122,35 @@ namespace osu.Game.Overlays.BeatmapSet base.OnHoverLost(state); } - private void updatePlayingState() + private void updatePlayingState(bool newValue) { - if (preview == null) return; - - if (Playing) + if (preview == null) { - icon.Icon = FontAwesome.fa_stop; - progress.FadeIn(100); + playButton.Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet.OnlineInfo.Preview) + { + OnLoadComplete = d => + { + playButton.Loading = false; - preview.Seek(0); - preview.Start(); + preview = (d as AudioLoadWrapper)?.Preview; + playing.TriggerChange(); + }, + }); } else { - icon.Icon = FontAwesome.fa_play; - progress.FadeOut(100); - preview.Stop(); - } - } - - private class AudioLoadWrapper : Drawable - { - private readonly string preview; - - public Track Preview; - - public AudioLoadWrapper(BeatmapSetInfo set) - { - preview = set.OnlineInfo.Preview; - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - if (!string.IsNullOrEmpty(preview)) + if (newValue) { - Preview = audio.Track.Get(preview); - Preview.Volume.Value = 0.5; + progress.FadeIn(100); + + preview.Seek(0); + preview.Start(); + } + else + { + progress.FadeOut(100); + preview.Stop(); } } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 8a26ae906d..3b8cd20200 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -26,6 +26,7 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; + protected override Box PreviewBar => progressBar; public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { @@ -197,20 +198,8 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), Alpha = 0, - TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, }); - - PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - } - - protected override void Update() - { - base.Update(); - - if (PreviewPlaying && playButton.Track != null) - progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } } } diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index a9d7993f7a..6a73c15ee6 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -14,6 +14,7 @@ using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Configuration; +using System; namespace osu.Game.Overlays.Direct { @@ -33,6 +34,7 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; + protected override Box PreviewBar => progressBar; [BackgroundDependencyLoader] private void load(LocalisationEngine localisation, OsuColour colours) @@ -70,7 +72,6 @@ namespace osu.Game.Overlays.Direct Size = new Vector2(height / 2), FillMode = FillMode.Fit, Alpha = 0, - TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { @@ -165,17 +166,6 @@ namespace osu.Game.Overlays.Direct Colour = colours.Yellow, }, }); - - PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - } - - protected override void Update() - { - base.Update(); - - if (PreviewPlaying && playButton.Track != null) - progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index c4c20da297..6b1e06fd3a 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -21,6 +21,8 @@ using osu.Framework.Logging; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; using osu.Framework.Configuration; +using osu.Framework.Audio.Track; +using osu.Game.Audio; namespace osu.Game.Overlays.Direct { @@ -39,9 +41,12 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; private BeatmapSetOverlay beatmapSetOverlay; + private Container audioWrapper; + protected Track Preview; public readonly Bindable PreviewPlaying = new Bindable(); protected abstract PlayButton PlayButton { get; } + protected abstract Box PreviewBar { get; } protected override Container Content => content; @@ -82,6 +87,7 @@ namespace osu.Game.Overlays.Direct EdgeEffect = edgeEffectNormal, Children = new[] { + audioWrapper = new Container(), // temporary blackness until the actual background loads. BlackBackground = new Box { @@ -106,6 +112,53 @@ namespace osu.Game.Overlays.Direct if (downloadRequest != null) attachDownload(downloadRequest); + + PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += setPlaying; + } + + private void setPlaying(bool newValue) + { + if (newValue) + { + if(Preview == null) + { + PlayButton.Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") + { + OnLoadComplete = d => + { + PlayButton.Loading = false; + Preview = (d as AudioLoadWrapper)?.Preview; + Preview.Start(); + }, + }); + } + else + { + Preview.Start(); + } + } + else + { + Preview?.Stop(); + } + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && Preview != null) + { + PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length); + if (Preview.HasCompleted) + { + PreviewPlaying.Value = false; + Preview = null; + } + } } protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index b0d011a81c..34b0ace1c5 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -11,81 +11,70 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using System.Threading.Tasks; namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - public string TrackUrl; - - public Bindable Playing; - - public Track Track; - private Bindable gameBeatmap; - private AudioManager audio; + private readonly Bindable playing; private Color4 hoverColour; private readonly SpriteIcon icon; + private readonly LoadingAnimation loadingAnimation; + private const float transition_duration = 500; + + private bool loading; + public bool Loading + { + get { return loading; } + set + { + loading = value; + if (value) + { + loadingAnimation.Show(); + icon.FadeOut(transition_duration * 5, Easing.OutQuint); + } + else + { + loadingAnimation.Hide(); + icon.FadeIn(transition_duration, Easing.OutQuint); + } + } + } public PlayButton(Bindable playing) { - Playing = playing; - Add(icon = new SpriteIcon + this.playing = playing; + AddRange(new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fit, - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.fa_play, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.fa_play, + }, + loadingAnimation = new LoadingAnimation(), }); - Playing.ValueChanged += newValue => icon.Icon = newValue ? (Track == null ? FontAwesome.fa_spinner : FontAwesome.fa_pause) : FontAwesome.fa_play; + playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; - Playing.ValueChanged += newValue => - { - if (newValue) - Track?.Start(); - else - Track?.Stop(); - }; - - Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); } [BackgroundDependencyLoader] - private void load(OsuColour colour, OsuGameBase game, AudioManager audio) + private void load(OsuColour colour) { hoverColour = colour.Yellow; - gameBeatmap = game.Beatmap; - this.audio = audio; } - private Task loadTask; - protected override bool OnClick(InputState state) { - gameBeatmap.Value.Track.Stop(); - - Playing.Value = !Playing.Value; - - if (loadTask == null) - { - icon.Spin(2000, RotationDirection.Clockwise); - - loadTask = Task.Run(() => - { - Track = audio.Track.Get(TrackUrl); - Track.Looping = true; - if (Playing) - Track.Start(); - - icon.ClearTransforms(); - icon.Rotation = 0; - Playing.TriggerChange(); - }); - } - + playing.Value = !playing.Value; return true; } @@ -97,7 +86,7 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!Playing) + if(!playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 95a15c06ba..3d81c5a539 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,6 +239,7 @@ + From 26e7a3f157ced6e6fb0ab01f05b9ec2abe2ab862 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:12:12 +0200 Subject: [PATCH 26/90] add license header --- osu.Game/Audio/AudioLoadWrapper.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index 8c013cf70f..69bf9d8147 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; From 2457df8e18b88006b3ecae32dd1ab0ac970a79e1 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:26:16 +0200 Subject: [PATCH 27/90] remove unused usings and reset the track to the start when playing again --- osu.Game/Audio/AudioLoadWrapper.cs | 5 ----- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 2 -- osu.Game/Overlays/Direct/DirectGridPanel.cs | 1 - osu.Game/Overlays/Direct/DirectListPanel.cs | 2 -- osu.Game/Overlays/Direct/DirectPanel.cs | 3 ++- osu.Game/Overlays/Direct/PlayButton.cs | 4 ---- 6 files changed, 2 insertions(+), 15 deletions(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index 69bf9d8147..efdde48564 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -6,11 +6,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Game.Beatmaps; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace osu.Game.Audio { diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index 9bb8b9a1a5..ea49963f67 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -12,7 +11,6 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; using osu.Game.Audio; diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 3b8cd20200..10611cd5be 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 6a73c15ee6..7f5fa3e3f0 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -13,8 +13,6 @@ using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Framework.Configuration; -using System; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 6b1e06fd3a..2195fc9ce7 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -131,12 +131,13 @@ namespace osu.Game.Overlays.Direct { PlayButton.Loading = false; Preview = (d as AudioLoadWrapper)?.Preview; - Preview.Start(); + PreviewPlaying.TriggerChange(); }, }); } else { + Preview.Seek(0); Preview.Start(); } } diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 34b0ace1c5..0405049c6a 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -3,16 +3,12 @@ using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using System.Threading.Tasks; namespace osu.Game.Overlays.Direct { From 59247bcf1eeef982a1ab442afcef0c3afa055561 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:31:42 +0200 Subject: [PATCH 28/90] another unused using --- osu.Game/Audio/AudioLoadWrapper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index efdde48564..67836d1690 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; -using osu.Game.Beatmaps; namespace osu.Game.Audio { From 1a7e3fa09e4d51db6a30dfe7975538fc1277b824 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 19:21:08 +0900 Subject: [PATCH 29/90] Initial implementation of a test case which showcases waveforms --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 ++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 150 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseWaveform.cs diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs new file mode 100644 index 0000000000..5f4e86fb92 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -0,0 +1,149 @@ +// 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 OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; + +namespace osu.Game.Tests.Visual +{ + internal class TestCaseWaveform : OsuTestCase + { + private readonly Bindable beatmapBacking = new Bindable(); + + private readonly List displays = new List(); + + public TestCaseWaveform() + { + MusicController mc; + FillFlowContainer flow; + Child = flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + mc = new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = 100, + State = Visibility.Visible + }, + } + }; + + for (int i = 1; i <= 16; i *= 2) + { + var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + + displays.Add(newDisplay); + + flow.Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 100, + Children = new Drawable[] + { + newDisplay, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.75f + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = $"Resolution: {(1f / i).ToString("0.00")}" + } + } + } + } + }); + } + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); + } + + private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + + private class WaveformDisplay : CompositeDrawable + { + private readonly int resolution; + + public WaveformDisplay(int resolution) + { + this.resolution = resolution; + } + + public void Display(Waveform waveform) + { + ClearInternal(); + + var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + + for (int i = 0; i < generated.Count; i++) + { + var point = generated[i]; + + // Left channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), + Colour = Color4.Red + }); + + if (waveform.Channels >= 2) + { + // Right channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.TopLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), + Colour = Color4.Green + }); + } + } + } + + private class NonInputBox : Box + { + public override bool HandleInput => false; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a8536bbc2..56490b6119 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -777,6 +777,7 @@ + From 319649f4465a45bc93c615d57ceb11ac36cd8460 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 21:19:38 +0900 Subject: [PATCH 30/90] Make TestCaseWaveform use a custom drawnode instead of boxes --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 128 +++++++++++++++++----- 1 file changed, 101 insertions(+), 27 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 5f4e86fb92..3f71e74a8d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -5,12 +5,19 @@ using System; using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; +using OpenTK.Graphics.ES30; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -92,51 +99,118 @@ namespace osu.Game.Tests.Visual private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); - private class WaveformDisplay : CompositeDrawable + private class WaveformDisplay : Drawable { + private List points; + private int channels; + + private Shader shader; + private readonly Texture texture; + private readonly int resolution; public WaveformDisplay(int resolution) { this.resolution = resolution; + + texture = Texture.WhitePixel; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } public void Display(Waveform waveform) { - ClearInternal(); + points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + channels = waveform.Channels; + Invalidate(Invalidation.DrawNode); + } - var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - for (int i = 0; i < generated.Count; i++) + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Points = points; + n.Channels = channels; + n.Size = DrawSize; + n.Shared = sharedData; + + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) { - var point = generated[i]; + base.Draw(vertexAction); - // Left channel - AddInternal(new NonInputBox - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), - Colour = Color4.Red - }); + if (Points == null || Points.Count == 0) + return; - if (waveform.Channels >= 2) + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) { - // Right channel - AddInternal(new NonInputBox + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) { - Anchor = Anchor.CentreLeft, - Origin = Anchor.TopLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), - Colour = Color4.Green - }); + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); } + + Shader.Unbind(); } } From 3eeb36cbd42f3cfa4b7b448e9c4170af4a346601 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 23:23:20 +0900 Subject: [PATCH 31/90] Remove now unused class --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 3f71e74a8d..2966728fb5 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -143,7 +143,6 @@ namespace osu.Game.Tests.Visual n.Size = DrawSize; n.Shared = sharedData; - base.ApplyDrawNode(node); } @@ -213,11 +212,6 @@ namespace osu.Game.Tests.Visual Shader.Unbind(); } } - - private class NonInputBox : Box - { - public override bool HandleInput => false; - } } } } From a37b10d51220b5f0df864cd8e503696eb669a0b6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:42:22 +0900 Subject: [PATCH 32/90] Make TestCaseWaveform use invalidations + remove some of the crud --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 69 +++++++++++++++-------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 2966728fb5..4df7ffe367 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -28,8 +28,6 @@ namespace osu.Game.Tests.Visual { private readonly Bindable beatmapBacking = new Bindable(); - private readonly List displays = new List(); - public TestCaseWaveform() { MusicController mc; @@ -53,9 +51,13 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + var newDisplay = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Resolution = 1f / i + }; - displays.Add(newDisplay); + newDisplay.Beatmap.BindTo(beatmapBacking); flow.Add(new Container { @@ -91,29 +93,21 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - beatmapBacking.BindTo(osuGame.Beatmap); - beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); - } - - private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); private class WaveformDisplay : Drawable { - private List points; - private int channels; + public readonly Bindable Beatmap = new Bindable(); + + private Waveform waveform; private Shader shader; private readonly Texture texture; - private readonly int resolution; - - public WaveformDisplay(int resolution) + public WaveformDisplay() { - this.resolution = resolution; - texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; } [BackgroundDependencyLoader] @@ -122,26 +116,51 @@ namespace osu.Game.Tests.Visual shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } - public void Display(Waveform waveform) + private float resolution = 1; + public float Resolution { - points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); - channels = waveform.Channels; - Invalidate(Invalidation.DrawNode); + get { return resolution; } + set + { + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } } - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + private Track lastQueriedTrack; + + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); protected override void ApplyDrawNode(DrawNode node) { var n = (WaveformDrawNode)node; n.Shader = shader; n.Texture = texture; - n.Points = points; - n.Channels = channels; n.Size = DrawSize; n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; base.ApplyDrawNode(node); } From 01c839eda7dfeb6f68edf6b6a442e956f6715c60 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:55:17 +0900 Subject: [PATCH 33/90] Move WaveformDisplay into separate class and add some commenting --- .../Edit/Screens/Compose/WaveformDisplay.cs | 168 ++++++++++++++++++ osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 +--------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 170 insertions(+), 148 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs new file mode 100644 index 0000000000..0f0c32ea0d --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -0,0 +1,168 @@ +// 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 OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class WaveformDisplay : Drawable + { + /// + /// The beatmap which the audio waveform should be displayed for. + /// + /// + public readonly Bindable Beatmap = new Bindable(); + + private Shader shader; + private readonly Texture texture; + + public WaveformDisplay() + { + texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + } + + private float resolution = 1; + /// + /// Controls the amount of interpolation of the waveform into the width of this . + /// Points in the waveform are interpolated between 1 / pixels of this . + /// + /// + public float Resolution + { + get { return resolution; } + set + { + if (value < 0 || value > 1) + throw new ArgumentOutOfRangeException(nameof(value)); + + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } + } + + private Waveform waveform; + private Track lastQueriedTrack; + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } + + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Size = DrawSize; + n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + if (Points == null || Points.Count == 0) + return; + + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) + { + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) + { + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); + } + + Shader.Unbind(); + } + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4df7ffe367..0430185bf7 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -1,26 +1,17 @@ // 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 OpenTK; using OpenTK.Graphics; -using OpenTK.Graphics.ES30; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; namespace osu.Game.Tests.Visual { @@ -94,143 +85,5 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); - - private class WaveformDisplay : Drawable - { - public readonly Bindable Beatmap = new Bindable(); - - private Waveform waveform; - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - public float Resolution - { - get { return resolution; } - set - { - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Track lastQueriedTrack; - - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); - n.Channels = waveform.Channels; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56490b6119..f89810dfc1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -620,6 +620,7 @@ + From 80e984f72dea9361b6b2d53cb9bdbe42614412d2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:38 +0900 Subject: [PATCH 34/90] Update in-line with framework --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 0f0c32ea0d..a781e63fd9 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); n.Channels = waveform.Channels; base.ApplyDrawNode(node); From 81960c7b487d2a66b134ad9554d0a639153a2483 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:45 +0900 Subject: [PATCH 35/90] CI fixes --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 -- osu.Game/Tests/Visual/TestCaseWaveform.cs | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index a781e63fd9..236f6b6d47 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// /// The beatmap which the audio waveform should be displayed for. /// - /// public readonly Bindable Beatmap = new Bindable(); private Shader shader; @@ -46,7 +45,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// Controls the amount of interpolation of the waveform into the width of this . /// Points in the waveform are interpolated between 1 / pixels of this . /// - /// public float Resolution { get { return resolution; } diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 0430185bf7..eff4f5cdad 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -21,7 +21,6 @@ namespace osu.Game.Tests.Visual public TestCaseWaveform() { - MusicController mc; FillFlowContainer flow; Child = flow = new FillFlowContainer { @@ -30,7 +29,7 @@ namespace osu.Game.Tests.Visual Spacing = new Vector2(0, 10), Children = new Drawable[] { - mc = new MusicController + new MusicController { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -74,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i).ToString("0.00")}" + Text = $"Resolution: {(1f / i):0.00}" } } } From 5ca4a2d2c81600178816afb37778e40ce480f47c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:09:39 +0900 Subject: [PATCH 36/90] Add some nullchecks to WaveformDisplay --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 236f6b6d47..d1550117df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,8 +90,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); - n.Channels = waveform.Channels; + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); } From 1377f73b460b90f7fd4037b51536cb36a7fff92f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:29 +0900 Subject: [PATCH 37/90] Multiply resolution before clamping --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index d1550117df..e11cd667e6 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); From ea4545299386900ba257dadcb25f7a0960901884 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:46 +0900 Subject: [PATCH 38/90] Allow resolution > 1 --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index e11cd667e6..3856558a32 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose get { return resolution; } set { - if (value < 0 || value > 1) + if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); if (resolution == value) From 8427bb44d18759b516865d49fd648327e3d14c99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:10:01 +0900 Subject: [PATCH 39/90] Implement basic layout for the compose screen ScrollableTimeline --- .../Screens/Compose/ScrollableTimeline.cs | 143 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 46 ++++++ osu.Game/osu.Game.csproj | 2 + 3 files changed, 191 insertions(+) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs create mode 100644 osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs new file mode 100644 index 0000000000..31d207a152 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -0,0 +1,143 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class ScrollableTimeline : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly Container timelineContainer; + private readonly WaveformDisplay waveform; + + public ScrollableTimeline() + { + Masking = true; + CornerRadius = 5; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 25 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + new OsuCheckbox { LabelText = "Hit Objects" }, + new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Waveform" } + } + } + } + }, + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 30), + Children = new[] + { + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_plus, + Colour = OsuColour.FromHex("555") + }, + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_minus, + Colour = OsuColour.FromHex("555") + }, + } + } + } + }, + timelineContainer = new Container + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + waveform = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("081a84") + // Resolution = 0.33f, + } + } + } + } + } + }; + + waveform.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return false; + + waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); + return true; + } + + protected override void Update() + { + base.Update(); + + timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs new file mode 100644 index 0000000000..714c7b5d50 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -0,0 +1,46 @@ +// 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 OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseEditorComposeTimeline : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(WaveformDisplay) }; + + private readonly ScrollableTimeline timeline; + + public TestCaseEditorComposeTimeline() + { + Children = new Drawable[] + { + new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + State = Visibility.Visible + }, + timeline = new ScrollableTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1000, 100) + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + timeline.Beatmap.BindTo(osuGame.Beatmap); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fde38848f1..d9c98e9b92 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -622,6 +622,7 @@ + @@ -748,6 +749,7 @@ + From e9bc5dbd0f5e18cb0520596303cf021acc3f6c5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 23:35:20 +0900 Subject: [PATCH 40/90] Include framework commits --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 9d142a8e00..bcd92492a9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9d142a8e009794dfee828392e36025d08577131d +Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde From 0a9d23b4bad1da2081f720a3227319d10bbd11df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:39 +0900 Subject: [PATCH 41/90] Update with framework changes (removal of WaveformDisplay) --- osu-framework | 2 +- .../Screens/Compose/BeatmapWaveformGraph.cs | 33 ++++ .../Edit/Screens/Compose/WaveformDisplay.cs | 166 ------------------ osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 36 insertions(+), 169 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs delete mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu-framework b/osu-framework index bcd92492a9..4019939ba9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde +Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs new file mode 100644 index 0000000000..ceabda5b16 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class BeatmapWaveformGraph : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly WaveformGraph graph; + + public BeatmapWaveformGraph() + { + InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; + Beatmap.ValueChanged += b => graph.Track = b.Track; + } + + /// + /// Gets or sets the . + /// + public float Resolution + { + get { return graph.Resolution; } + set { graph.Resolution = value; } + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs deleted file mode 100644 index 3856558a32..0000000000 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ /dev/null @@ -1,166 +0,0 @@ -// 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 OpenTK; -using osu.Framework.Allocation; -using osu.Framework.Audio.Track; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; -using osu.Framework.Graphics.Textures; -using osu.Game.Beatmaps; - -namespace osu.Game.Screens.Edit.Screens.Compose -{ - public class WaveformDisplay : Drawable - { - /// - /// The beatmap which the audio waveform should be displayed for. - /// - public readonly Bindable Beatmap = new Bindable(); - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - /// - /// Controls the amount of interpolation of the waveform into the width of this . - /// Points in the waveform are interpolated between 1 / pixels of this . - /// - public float Resolution - { - get { return resolution; } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value)); - - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Waveform waveform; - private Track lastQueriedTrack; - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); - n.Channels = waveform?.Channels ?? 0; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } -} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index eff4f5cdad..531005af10 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay + var newDisplay = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Resolution = 1f / i diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f89810dfc1..106e4bfc3b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,6 +266,7 @@ + @@ -620,7 +621,6 @@ - From 7926757898ea4b12579f6fae8abce00e89a754ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:49 +0900 Subject: [PATCH 42/90] Remove unneeded parens --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 531005af10..4a6e93c7bf 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i):0.00}" + Text = $"Resolution: {1f / i:0.00}" } } } From 5a8b8dacbb99c6dfb17f702cd4aedf823bc85878 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 6 Oct 2017 21:00:23 +0200 Subject: [PATCH 43/90] move stuff thats duplicated in PreviewButton and DirectPanel to PlayButton --- osu.Game/Audio/AudioLoadWrapper.cs | 32 ------ osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 58 ++--------- osu.Game/Overlays/Direct/DirectGridPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 48 ++------- osu.Game/Overlays/Direct/PlayButton.cs | 99 +++++++++++++++++-- osu.Game/Overlays/DirectOverlay.cs | 22 ++--- osu.Game/osu.Game.csproj | 1 - 8 files changed, 117 insertions(+), 147 deletions(-) delete mode 100644 osu.Game/Audio/AudioLoadWrapper.cs diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs deleted file mode 100644 index 67836d1690..0000000000 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ /dev/null @@ -1,32 +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.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; -using osu.Framework.Graphics; - -namespace osu.Game.Audio -{ - public class AudioLoadWrapper : Drawable - { - private readonly string preview; - - public Track Preview; - - public AudioLoadWrapper(string preview) - { - this.preview = preview; - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - if (!string.IsNullOrEmpty(preview)) - { - Preview = audio.Track.Get(preview); - Preview.Volume.Value = 0.5; - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index ea49963f67..2fe2edaf1d 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -27,21 +27,13 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box bg, progress; private readonly PlayButton playButton; - private Track preview; - private readonly Bindable playing = new Bindable(); + private Track preview => playButton.Preview; + private Bindable playing => playButton.Playing; - private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet { - get { return beatmapSet; } - set - { - if (value == beatmapSet) return; - beatmapSet = value; - - playing.Value = false; - preview = null; - } + get { return playButton.SetInfo; } + set { playButton.SetInfo = value; } } public PreviewButton() @@ -69,7 +61,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - playButton = new PlayButton(playing) + playButton = new PlayButton() { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -78,7 +70,7 @@ namespace osu.Game.Overlays.BeatmapSet }; Action = () => playing.Value = !playing.Value; - playing.ValueChanged += updatePlayingState; + playing.ValueChanged += newValue => progress.FadeTo(newValue ? 1 : 0, 100); } [BackgroundDependencyLoader] @@ -94,11 +86,6 @@ namespace osu.Game.Overlays.BeatmapSet if (playing.Value && preview != null) { progress.Width = (float)(preview.CurrentTime / preview.Length); - if (preview.HasCompleted) - { - playing.Value = false; - preview = null; - } } } @@ -119,38 +106,5 @@ namespace osu.Game.Overlays.BeatmapSet bg.FadeColour(Color4.Black.Opacity(0.25f), 100); base.OnHoverLost(state); } - - private void updatePlayingState(bool newValue) - { - if (preview == null) - { - playButton.Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet.OnlineInfo.Preview) - { - OnLoadComplete = d => - { - playButton.Loading = false; - - preview = (d as AudioLoadWrapper)?.Preview; - playing.TriggerChange(); - }, - }); - } - else - { - if (newValue) - { - progress.FadeIn(100); - - preview.Seek(0); - preview.Start(); - } - else - { - progress.FadeOut(100); - preview.Stop(); - } - } - } } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 10611cd5be..7464ee7fb8 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -192,7 +192,7 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, - playButton = new PlayButton(PreviewPlaying) + playButton = new PlayButton(SetInfo) { Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7f5fa3e3f0..5889a1bc12 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.Direct Spacing = new Vector2(10, 0), Children = new Drawable[] { - playButton = new PlayButton(PreviewPlaying) + playButton = new PlayButton(SetInfo) { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 2195fc9ce7..eaabb0b539 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -41,10 +41,9 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; private BeatmapSetOverlay beatmapSetOverlay; - private Container audioWrapper; - protected Track Preview; - public readonly Bindable PreviewPlaying = new Bindable(); + public Track Preview => PlayButton.Preview; + public Bindable PreviewPlaying => PlayButton.Playing; protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } @@ -87,7 +86,6 @@ namespace osu.Game.Overlays.Direct EdgeEffect = edgeEffectNormal, Children = new[] { - audioWrapper = new Container(), // temporary blackness until the actual background loads. BlackBackground = new Box { @@ -112,39 +110,6 @@ namespace osu.Game.Overlays.Direct if (downloadRequest != null) attachDownload(downloadRequest); - - PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += setPlaying; - } - - private void setPlaying(bool newValue) - { - if (newValue) - { - if(Preview == null) - { - PlayButton.Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") - { - OnLoadComplete = d => - { - PlayButton.Loading = false; - Preview = (d as AudioLoadWrapper)?.Preview; - PreviewPlaying.TriggerChange(); - }, - }); - } - else - { - Preview.Seek(0); - Preview.Start(); - } - } - else - { - Preview?.Stop(); - } } protected override void Update() @@ -154,11 +119,6 @@ namespace osu.Game.Overlays.Direct if (PreviewPlaying && Preview != null) { PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length); - if (Preview.HasCompleted) - { - PreviewPlaying.Value = false; - Preview = null; - } } } @@ -184,6 +144,7 @@ namespace osu.Game.Overlays.Direct protected override bool OnClick(InputState state) { ShowInformation(); + PreviewPlaying.Value = false; return true; } @@ -244,6 +205,9 @@ namespace osu.Game.Overlays.Direct { base.LoadComplete(); this.FadeInFromZero(200, Easing.Out); + + PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); } protected List GetDifficultyIcons() diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 0405049c6a..dea6b1568d 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -3,10 +3,14 @@ using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -14,11 +18,28 @@ namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - private readonly Bindable playing; + public readonly Bindable Playing = new Bindable(); + public Track Preview { get; private set; } + + private BeatmapSetInfo setInfo; + public BeatmapSetInfo SetInfo + { + get { return setInfo; } + set + { + if (value == setInfo) return; + setInfo = value; + + Playing.Value = false; + Preview = null; + } + } private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; + private Container audioWrapper; + private const float transition_duration = 500; private bool loading; @@ -41,11 +62,12 @@ namespace osu.Game.Overlays.Direct } } - public PlayButton(Bindable playing) + public PlayButton(BeatmapSetInfo setInfo = null) { - this.playing = playing; + this.SetInfo = setInfo; AddRange(new Drawable[] { + audioWrapper = new Container(), icon = new SpriteIcon { Anchor = Anchor.Centre, @@ -57,9 +79,10 @@ namespace osu.Game.Overlays.Direct loadingAnimation = new LoadingAnimation(), }); - playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; + Playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; + Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); - playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + Playing.ValueChanged += updatePreviewTrack; } [BackgroundDependencyLoader] @@ -70,7 +93,7 @@ namespace osu.Game.Overlays.Direct protected override bool OnClick(InputState state) { - playing.Value = !playing.Value; + Playing.Value = !Playing.Value; return true; } @@ -82,9 +105,71 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!playing.Value) + if(!Playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } + + protected override void Update() + { + base.Update(); + + if(Preview?.HasCompleted ?? false) + { + Playing.Value = false; + Preview = null; + } + } + + private void updatePreviewTrack(bool newValue) + { + if (newValue) + { + if (Preview == null) + { + Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") + { + OnLoadComplete = d => + { + Loading = false; + Preview = (d as AudioLoadWrapper)?.Preview; + Playing.TriggerChange(); + }, + }); + } + else + { + Preview.Seek(0); + Preview.Start(); + } + } + else + { + Preview?.Stop(); + } + } + + private class AudioLoadWrapper : Drawable + { + private readonly string preview; + + public Track Preview; + + public AudioLoadWrapper(string preview) + { + this.preview = preview; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + if (!string.IsNullOrEmpty(preview)) + { + Preview = audio.Track.Get(preview); + Preview.Volume.Value = 0.5; + } + } + } } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9d79e87b1d..71dc558b26 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -230,21 +230,21 @@ namespace osu.Game.Overlays }) }; - foreach (DirectPanel panel in newPanels.Children) - panel.PreviewPlaying.ValueChanged += newValue => - { - if (newValue) - { - if (playing != null && playing != panel) - playing.PreviewPlaying.Value = false; - playing = panel; - } - }; - LoadComponentAsync(newPanels, p => { if (panels != null) ScrollFlow.Remove(panels); ScrollFlow.Add(panels = newPanels); + + foreach (DirectPanel panel in p.Children) + panel.PreviewPlaying.ValueChanged += newValue => + { + if (newValue) + { + if (playing != null && playing != panel) + playing.PreviewPlaying.Value = false; + playing = panel; + } + }; }); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0b72e22d25..e374b7c274 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -238,7 +238,6 @@ - From f3ca6cc38756d3c2d121cb6a553bd72db37f5413 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 6 Oct 2017 21:06:37 +0200 Subject: [PATCH 44/90] remove redundant stuff --- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 5 +---- osu.Game/Overlays/Direct/DirectPanel.cs | 1 - osu.Game/Overlays/Direct/PlayButton.cs | 5 ++--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index 2fe2edaf1d..d040c89a91 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using OpenTK; using OpenTK.Graphics; -using osu.Game.Audio; using osu.Game.Overlays.Direct; using osu.Framework.Configuration; @@ -23,7 +22,6 @@ namespace osu.Game.Overlays.BeatmapSet { private const float transition_duration = 500; - private readonly Container audioWrapper; private readonly Box bg, progress; private readonly PlayButton playButton; @@ -42,7 +40,6 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - audioWrapper = new Container(), bg = new Box { RelativeSizeAxes = Axes.Both, @@ -61,7 +58,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - playButton = new PlayButton() + playButton = new PlayButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index eaabb0b539..ef89c0022b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -22,7 +22,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; using osu.Framework.Configuration; using osu.Framework.Audio.Track; -using osu.Game.Audio; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index dea6b1568d..9ccce134d8 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -9,7 +9,6 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -38,7 +37,7 @@ namespace osu.Game.Overlays.Direct private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; - private Container audioWrapper; + private readonly Container audioWrapper; private const float transition_duration = 500; @@ -64,7 +63,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(BeatmapSetInfo setInfo = null) { - this.SetInfo = setInfo; + SetInfo = setInfo; AddRange(new Drawable[] { audioWrapper = new Container(), From 19b38983dffa148f09441a20185dd0f8b6f70521 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 17:18:11 +0900 Subject: [PATCH 45/90] Update in-line with framework --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 ++++++++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 14 ++++++++++++++ .../Edit/Screens/Compose/BeatmapWaveformGraph.cs | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 4019939ba9..38cf96c899 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 +Subproject commit 38cf96c8994ad41ae6aa86de6bfe09fd5fa9e1b6 diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..5fcdab11f8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -573,6 +573,16 @@ namespace osu.Game.Beatmaps } catch { return new TrackVirtual(); } } + + protected override Waveform GetWaveform() + { + try + { + var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); + return trackData == null ? new Waveform() : new Waveform(trackData); + } + catch { return new Waveform(); } + } } /// diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 277846ee80..959e71d48d 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -43,6 +43,7 @@ namespace osu.Game.Beatmaps protected abstract Beatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); + protected virtual Waveform GetWaveform() => new Waveform(); private Beatmap beatmap; private readonly object beatmapLock = new object(); @@ -96,6 +97,17 @@ namespace osu.Game.Beatmaps } } + private Waveform waveform; + private readonly object waveformLock = new object(); + public Waveform Waveform + { + get + { + lock (waveformLock) + return waveform ?? (waveform = GetWaveform()); + } + } + public bool TrackLoaded => track != null; public void TransferTo(WorkingBeatmap other) @@ -114,6 +126,8 @@ namespace osu.Game.Beatmaps { background?.Dispose(); background = null; + + waveform?.Dispose(); } public void DisposeTrack() diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs index ceabda5b16..f204c8c525 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose public BeatmapWaveformGraph() { InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; - Beatmap.ValueChanged += b => graph.Track = b.Track; + Beatmap.ValueChanged += b => graph.Waveform = b.Waveform; } /// From 222d0c86942416d2999f217a2a1b1ada26189c64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 17:52:48 +0900 Subject: [PATCH 46/90] Fix visual regressions in MedalOverlay --- osu.Game/Overlays/MedalOverlay.cs | 2 +- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 9 ++++++--- osu.Game/Tests/Visual/TestCaseMedalOverlay.cs | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index 880b607e78..776f2ffadb 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -159,7 +159,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, }); } diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 3ac8af7b2b..ea51471199 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -90,6 +90,7 @@ namespace osu.Game.Overlays.MedalSplash }, description = new TextFlowContainer { + TextAnchor = Anchor.TopCentre, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, @@ -115,15 +116,16 @@ namespace osu.Game.Overlays.MedalSplash medalSprite.Texture = textures.Get(medal.ImageUrl); medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow"); description.Colour = colours.BlueLight; - - unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10); - infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } protected override void LoadComplete() { base.LoadComplete(); + updateState(); + + unlocked.Position = new Vector2(0f, medalContainer.DrawSize.Y / 2 + 10); + infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } public DisplayState State @@ -172,6 +174,7 @@ namespace osu.Game.Overlays.MedalSplash this.ScaleTo(scale_when_full, duration, Easing.OutExpo); this.MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, Easing.OutExpo); + unlocked.Show(); name.FadeInFromZero(duration + 100); description.FadeInFromZero(duration * 2); break; diff --git a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs index fecf37538b..9a26eefd63 100644 --- a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs @@ -1,7 +1,10 @@ // 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.Game.Overlays; +using osu.Game.Overlays.MedalSplash; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -10,6 +13,12 @@ namespace osu.Game.Tests.Visual { public override string Description => @"medal get!"; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MedalOverlay), + typeof(DrawableMedal), + }; + public TestCaseMedalOverlay() { AddStep(@"display", () => From 26215b448898a49af66749a8e4bbafe36aa45818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 19:42:55 +0900 Subject: [PATCH 47/90] Create an abstract base class for drawable catch objects --- .../Drawable/DrawableCatchHitObject.cs | 50 +++++++++++ .../Objects/Drawable/DrawableFruit.cs | 82 +++++-------------- .../osu.Game.Rulesets.Catch.csproj | 1 + 3 files changed, 72 insertions(+), 61 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs new file mode 100644 index 0000000000..fbb93e51a7 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject + { + protected DrawableCatchHitObject(CatchBaseHit hitObject) + : base(hitObject) + { + Origin = Anchor.Centre; + RelativePositionAxes = Axes.Both; + X = hitObject.X; + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + } + + public Func CheckPosition; + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (timeOffset > 0) + AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); + } + + private const float preempt = 1000; + + protected override void UpdateState(ArmedState state) + { + using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + { + // animation + this.FadeIn(200); + } + + switch (state) + { + case ArmedState.Miss: + using (BeginAbsoluteSequence(HitObject.StartTime, true)) + this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index e0c9f0c028..8e2618c64c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -1,72 +1,29 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableScrollingHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } - - public DrawableFruit(CatchBaseHit h) : base(h) { - Origin = Anchor.Centre; Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); - - RelativePositionAxes = Axes.Both; - X = h.X; - AccentColour = HitObject.ComboColour; - Masking = false; - - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } - public Func CheckPosition; - [BackgroundDependencyLoader] private void load() { @@ -115,28 +72,31 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } - private const float preempt = 1000; - - protected override void CheckForJudgements(bool userTriggered, double timeOffset) + private class Pulp : Circle, IHasAccentColour { - if (timeOffset > 0) - AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); - } - - protected override void UpdateState(ArmedState state) - { - using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + public Pulp() { - // animation - this.FadeIn(200); + Size = new Vector2(pulp_size); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); } - switch (state) + private Color4 accentColour; + public Color4 AccentColour { - case ArmedState.Miss: - using (BeginAbsoluteSequence(HitObject.StartTime, true)) - this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); - break; + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } } } } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 718ae32a17..f614ec647f 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -50,6 +50,7 @@ + From d1f02538cbc764175532d66318a4083c95a63a4c Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 9 Oct 2017 21:12:04 +0300 Subject: [PATCH 48/90] Add tooltip to username in the profile overlay --- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index d6a86fe714..742e865140 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using System.Diagnostics; using System.Globalization; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Profile { @@ -119,7 +120,7 @@ namespace osu.Game.Overlays.Profile } } }, - new LinkFlowContainer.LinkText + new LinkFlowContainer.BrowserLinkText { Text = user.Username, Url = $@"https://osu.ppy.sh/users/{user.Id}", @@ -539,6 +540,11 @@ namespace osu.Game.Overlays.Profile hoverColour = colours.Yellow; } } + + public class BrowserLinkText : LinkText, IHasTooltip + { + public string TooltipText => "View Profile in Browser"; + } } } } From 074a1db4a1969f64f29035be9340df947a710eac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 12:45:27 +0900 Subject: [PATCH 49/90] Implement scrolling and better zoom --- .../Screens/Compose/ScrollableTimeline.cs | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 7b2b52a239..5fc47958e2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -17,8 +17,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public readonly Bindable Beatmap = new Bindable(); - private readonly Container timelineContainer; - private readonly BeatmapWaveformGraph waveform; + private readonly ScrollingTimelineContainer timelineContainer; public ScrollableTimeline() { @@ -104,33 +103,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose } } }, - timelineContainer = new Container - { - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("081a84") - // Resolution = 0.33f, - } - } - } + timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y } } } }; - waveform.Beatmap.BindTo(Beatmap); - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return false; - - waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); - return true; + timelineContainer.Beatmap.BindTo(Beatmap); } protected override void Update() @@ -139,5 +117,49 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } + + private class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + + float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); + float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + + float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); + float scrollPos = newAbsoluteTarget - mousePos; + + Content.ResizeWidthTo(newSize); + ScrollTo(scrollPos, false); + + return true; + } + } } } From 166194e6b6f587c04cd0132a08dafab703416542 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:09:26 +0900 Subject: [PATCH 50/90] Further logic simplification --- .../Screens/Compose/ScrollableTimeline.cs | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 5fc47958e2..b5445883ab 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -142,20 +143,60 @@ namespace osu.Game.Screens.Edit.Screens.Compose graph.Beatmap.BindTo(Beatmap); } + private float minZoom = 1; + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + } + } + + private float maxZoom = 30; + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + } + } + + private float zoom = 1; + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); - float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + Zoom += state.Mouse.WheelDelta; - float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); - float scrollPos = newAbsoluteTarget - mousePos; - - Content.ResizeWidthTo(newSize); + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; ScrollTo(scrollPos, false); return true; From 1cf8c0284a3503c09c0f486c5d6b12f0f937f5ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:22:32 +0900 Subject: [PATCH 51/90] Re-namespace a few classes --- .../{ => Timeline}/BeatmapWaveformGraph.cs | 2 +- .../{ => Timeline}/ScrollableTimeline.cs | 86 +------------ .../Timeline/ScrollingTimelineContainer.cs | 113 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 3 +- osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 + osu.Game/osu.Game.csproj | 5 +- 6 files changed, 121 insertions(+), 89 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/BeatmapWaveformGraph.cs (91%) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/ScrollableTimeline.cs (63%) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs similarity index 91% rename from osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs index f204c8c525..5acee675e8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class BeatmapWaveformGraph : CompositeDrawable { diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs similarity index 63% rename from osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index b5445883ab..5999241f61 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -12,7 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollableTimeline : CompositeDrawable { @@ -118,89 +118,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } - - private class ScrollingTimelineContainer : ScrollContainer - { - public readonly Bindable Beatmap = new Bindable(); - - private readonly BeatmapWaveformGraph graph; - - public ScrollingTimelineContainer() - : base(Direction.Horizontal) - { - Masking = true; - - Add(graph = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, - }); - - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - - graph.Beatmap.BindTo(Beatmap); - } - - private float minZoom = 1; - public float MinZoom - { - get { return minZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (minZoom == value) - return; - minZoom = value; - } - } - - private float maxZoom = 30; - public float MaxZoom - { - get { return maxZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (maxZoom == value) - return; - maxZoom = value; - } - } - - private float zoom = 1; - public float Zoom - { - get { return zoom; } - set - { - value = MathHelper.Clamp(value, MinZoom, MaxZoom); - if (zoom == value) - return; - zoom = value; - - Content.ResizeWidthTo(Zoom); - } - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - - Zoom += state.Mouse.WheelDelta; - - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - - return true; - } - } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs new file mode 100644 index 0000000000..f4795452d5 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + internal class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + private float minZoom = 1; + /// + /// The minimum zoom level allowed. + /// + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float maxZoom = 30; + /// + /// The maximum zoom level allowed. + /// + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float zoom = 1; + /// + /// The current zoom level. + /// + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + + Zoom += state.Mouse.WheelDelta; + + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; + ScrollTo(scrollPos, false); + + return true; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 4ec3b8c661..40d617d2ea 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -9,12 +9,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4a6e93c7bf..c87be7e4b8 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b1d410ba50..321c2df4b5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,7 +266,7 @@ - + @@ -630,7 +630,8 @@ - + + From 03fbf47bc2f1974a9518b36aa3921dfac055c332 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 16:34:01 +0900 Subject: [PATCH 52/90] Add juicy streams --- .../Beatmaps/CatchBeatmapConverter.cs | 30 ++++- .../Drawable/DrawableCatchHitObject.cs | 15 ++- .../Objects/Drawable/DrawableDroplet.cs | 32 +++++ .../Objects/Drawable/DrawableFruit.cs | 40 +----- .../Objects/Drawable/DrawableJuiceStream.cs | 59 ++++++++ .../Objects/Drawable/Pieces/Pulp.cs | 40 ++++++ .../Objects/JuiceStream.cs | 126 ++++++++++++++++++ .../Tests/TestCaseCatchPlayer.cs | 12 -- .../Tests/TestCaseCatchStacker.cs | 27 ++++ osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +- .../UI/CatchRulesetContainer.cs | 9 +- .../osu.Game.Rulesets.Catch.csproj | 10 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 2 + 13 files changed, 346 insertions(+), 62 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/JuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 2efb0c0707..b3ff1acb02 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -5,9 +5,9 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; using System; +using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -17,14 +17,36 @@ namespace osu.Game.Rulesets.Catch.Beatmaps protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap) { - if (!(obj is IHasXPosition)) + var curveData = obj as IHasCurve; + var positionData = obj as IHasPosition; + var comboData = obj as IHasCombo; + + if (positionData == null) yield break; + if (curveData != null) + { + yield return new JuiceStream + { + StartTime = obj.StartTime, + Samples = obj.Samples, + ControlPoints = curveData.ControlPoints, + CurveType = curveData.CurveType, + Distance = curveData.Distance, + RepeatSamples = curveData.RepeatSamples, + RepeatCount = curveData.RepeatCount, + X = positionData.X / CatchPlayfield.BASE_WIDTH, + NewCombo = comboData?.NewCombo ?? false + }; + + yield break; + } + yield return new Fruit { StartTime = obj.StartTime, - NewCombo = (obj as IHasCombo)?.NewCombo ?? false, - X = ((IHasXPosition)obj).X / OsuPlayfield.BASE_SIZE.X + NewCombo = comboData?.NewCombo ?? false, + X = positionData.X / CatchPlayfield.BASE_WIDTH }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index fbb93e51a7..bb2df401cb 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -3,12 +3,23 @@ using System; using osu.Framework.Graphics; -using osu.Framework.MathUtils; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable { + public abstract class DrawableCatchHitObject : DrawableCatchHitObject + where TObject : CatchBaseHit + { + public new TObject HitObject; + + protected DrawableCatchHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } + } + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject { protected DrawableCatchHitObject(CatchBaseHit hitObject) @@ -17,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + Y = (float)HitObject.StartTime; } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs new file mode 100644 index 0000000000..fdb8c3e1e5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableDroplet : DrawableCatchHitObject + { + public DrawableDroplet(Droplet h) + : base(h) + { + Size = new Vector2(Pulp.PULP_SIZE); + + AccentColour = Color4.Green; + Masking = false; + } + + [BackgroundDependencyLoader] + private void load() + { + Child = new Pulp + { + AccentColour = AccentColour, + Scale = new Vector2(0.6f), + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 8e2618c64c..336647cbb9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -2,26 +2,26 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableCatchHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - public DrawableFruit(CatchBaseHit h) + public DrawableFruit(Fruit h) : base(h) { Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; + + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] @@ -71,33 +71,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } }; } - - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs new file mode 100644 index 0000000000..162fe05fc5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -0,0 +1,59 @@ +// 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.Framework.Graphics.Containers; +using OpenTK; +using OpenTK.Graphics; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableJuiceStream : DrawableCatchHitObject + { + private readonly Container dropletContainer; + + public DrawableJuiceStream(JuiceStream s) : base(s) + { + RelativeSizeAxes = Axes.Both; + Height = (float)HitObject.Duration; + + Child = dropletContainer = new Container + { + RelativeSizeAxes = Axes.Both, + RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), + RelativeChildSize = new Vector2(1, (float)HitObject.Duration) + }; + + var start = new DrawableFruit(new Fruit + { + ComboColour = Color4.Blue, + StartTime = s.StartTime, + X = s.X, + }); + + AddNested(start); + + var end = new DrawableFruit(new Fruit + { + ComboColour = Color4.Red, + StartTime = s.EndTime, + X = s.EndX, + }); + + AddNested(end); + + foreach (var tick in s.Ticks) + { + var droplet = new DrawableDroplet(tick); + AddNested(droplet); + } + } + + protected override void AddNested(DrawableHitObject h) + { + dropletContainer.Add(h); + base.AddNested(h); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs new file mode 100644 index 0000000000..6a19bfa69a --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -0,0 +1,40 @@ +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces +{ + public class Pulp : Circle, IHasAccentColour + { + public const float PULP_SIZE = 20; + + public Pulp() + { + Size = new Vector2(PULP_SIZE); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); + } + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs new file mode 100644 index 0000000000..5213d67225 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -0,0 +1,126 @@ +// 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 System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class JuiceStream : CatchBaseHit, IHasCurve + { + /// + /// Scoring distance with a speed-adjusted beat length of 1 second. + /// + private const float base_scoring_distance = 100; + + public readonly SliderCurve Curve = new SliderCurve(); + + public int RepeatCount { get; set; } = 1; + + public double Velocity; + public double TickDistance; + + public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaults(controlPointInfo, difficulty); + + TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); + DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); + + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; + + Velocity = scoringDistance / timingPoint.BeatLength; + TickDistance = scoringDistance / difficulty.SliderTickRate; + } + + public IEnumerable Ticks + { + get + { + if (TickDistance == 0) yield break; + + var length = Curve.Distance; + var tickDistance = Math.Min(TickDistance, length); + var repeatDuration = length / Velocity; + + var minDistanceFromEnd = Velocity * 0.01; + + // temporary + while (tickDistance > 10) tickDistance /= 2; + + for (var repeat = 0; repeat < RepeatCount; repeat++) + { + var repeatStartTime = StartTime + repeat * repeatDuration; + var reversed = repeat % 2 == 1; + + for (var d = tickDistance; d <= length; d += tickDistance) + { + if (d > length - minDistanceFromEnd) + break; + + var distanceProgress = d / length; + var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + + yield return new Droplet + { + StartTime = repeatStartTime + timeProgress * repeatDuration, + X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }; + } + } + } + } + + public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity; + + public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH; + + public double Duration => EndTime - StartTime; + + public double Distance + { + get { return Curve.Distance; } + set { Curve.Distance = value; } + } + + public List ControlPoints + { + get { return Curve.ControlPoints; } + set { Curve.ControlPoints = value; } + } + + public List RepeatSamples { get; set; } = new List(); + + public CurveType CurveType + { + get { return Curve.CurveType; } + set { Curve.CurveType = value; } + } + + public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress)); + + public double ProgressAt(double progress) + { + double p = progress * RepeatCount % 1; + if (RepeatAt(progress) % 2 == 1) + p = 1 - p; + return p; + } + + public int RepeatAt(double progress) => (int)(progress * RepeatCount); + } +} diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index 5be07e94c0..25c095426f 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Tests { @@ -13,15 +11,5 @@ namespace osu.Game.Rulesets.Catch.Tests public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) { } - - protected override Beatmap CreateBeatmap() - { - var beatmap = new Beatmap(); - - for (int i = 0; i < 256; i++) - beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); - - return beatmap; - } } } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs new file mode 100644 index 0000000000..7c3bb2bfd8 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Tests +{ + [TestFixture] + public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer + { + public TestCaseCatchStacker() : base(typeof(CatchRuleset)) + { + } + + protected override Beatmap CreateBeatmap() + { + var beatmap = new Beatmap(); + + for (int i = 0; i < 256; i++) + beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); + + return beatmap; + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index c4033b562d..4d7af0f2b6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchPlayfield : ScrollingPlayfield { + public static readonly float BASE_WIDTH = 512; + protected override Container Content => content; private readonly Container content; @@ -28,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI Reversed.Value = true; - Size = new Vector2(1); - Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.UI base.Add(h); - var fruit = (DrawableFruit)h; + var fruit = (DrawableCatchHitObject)h; fruit.CheckPosition = CheckIfWeCanCatch; } diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 8a6ef71996..92912eb177 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -32,8 +32,13 @@ namespace osu.Game.Rulesets.Catch.UI protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { - if (h is Fruit) - return new DrawableFruit(h); + var fruit = h as Fruit; + if (fruit != null) + return new DrawableFruit(fruit); + + var stream = h as JuiceStream; + if (stream != null) + return new DrawableJuiceStream(stream); return null; } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index f614ec647f..906b7d663a 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -51,6 +51,10 @@ + + + + @@ -59,6 +63,7 @@ + @@ -80,11 +85,6 @@ osu.Framework False - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - False - {2a66dd92-adb1-4994-89e2-c94e04acda0d} osu.Game diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index 8bf85e498c..f920f97790 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; + public double Scale = 1; + public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; From e4f915e5af0f888a24884a8510eb2fead96a6357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 20:22:57 +0900 Subject: [PATCH 53/90] Fix scoring simulation not supporting juice --- .../Scoring/CatchScoreProcessor.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 16756e65f1..66a5636b74 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -21,6 +21,19 @@ namespace osu.Game.Rulesets.Catch.Scoring { foreach (var obj in beatmap.HitObjects) { + var stream = obj as JuiceStream; + + if (stream != null) + { + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + foreach (var unused in stream.Ticks) + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + continue; + } + var fruit = obj as Fruit; if (fruit != null) From 1f1bdc6162eb972da2c7557305533f8c14a74cb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 18:18:06 +0900 Subject: [PATCH 54/90] Make juice streams interactive (and correctly positioned) --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 1 + .../Objects/Drawable/DrawableCatchHitObject.cs | 1 - osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 3 +++ osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 2 ++ .../Objects/Drawable/DrawableJuiceStream.cs | 4 ++++ osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +++++- 7 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index b3ff1acb02..0e4935aa7a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps yield return new Fruit { StartTime = obj.StartTime, + Samples = obj.Samples, NewCombo = comboData?.NewCombo ?? false, X = positionData.X / CatchPlayfield.BASE_WIDTH }; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index bb2df401cb..e057bf3d8e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -25,7 +25,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected DrawableCatchHitObject(CatchBaseHit hitObject) : base(hitObject) { - Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; Y = (float)HitObject.StartTime; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fdb8c3e1e5..aedef33cfd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; @@ -13,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableDroplet(Droplet h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(Pulp.PULP_SIZE); AccentColour = Color4.Green; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 336647cbb9..cffb2981bf 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableFruit(Fruit h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 162fe05fc5..19fe43a862 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; + X = 0; Child = dropletContainer = new Container { @@ -27,6 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var start = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Blue, StartTime = s.StartTime, X = s.X, @@ -36,6 +38,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var end = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Red, StartTime = s.EndTime, X = s.EndX, @@ -52,6 +55,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void AddNested(DrawableHitObject h) { + ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; dropletContainer.Add(h); base.AddNested(h); } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 5213d67225..fa19a6ff15 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; // temporary - while (tickDistance > 10) tickDistance /= 2; + while (tickDistance > 100) tickDistance /= 2; for (var repeat = 0; repeat < RepeatCount; repeat++) { diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4d7af0f2b6..987eef5e45 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -83,7 +83,11 @@ namespace osu.Game.Rulesets.Catch.UI if (judgement.IsHit) { Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; - Remove(judgedObject); + + // todo: don't do this + (judgedObject.Parent as Container)?.Remove(judgedObject); + (judgedObject.Parent as Container)?.Remove(judgedObject); + catcher.Add(judgedObject, screenPosition); } } From 1b732c799a5b5a9bb285e74cc145c94c45d1201d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 19:10:07 +0900 Subject: [PATCH 55/90] Make all juice nested objects from ticks --- .../Objects/Drawable/DrawableJuiceStream.cs | 29 +++++-------------- .../Objects/JuiceStream.cs | 25 ++++++++++++---- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19fe43a862..fe54397d18 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -26,30 +26,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable RelativeChildSize = new Vector2(1, (float)HitObject.Duration) }; - var start = new DrawableFruit(new Fruit + foreach (CatchBaseHit tick in s.Ticks) { - Samples = s.Samples, - ComboColour = Color4.Blue, - StartTime = s.StartTime, - X = s.X, - }); + Droplet droplet = tick as Droplet; + if (droplet != null) + AddNested(new DrawableDroplet(droplet)); - AddNested(start); - - var end = new DrawableFruit(new Fruit - { - Samples = s.Samples, - ComboColour = Color4.Red, - StartTime = s.EndTime, - X = s.EndX, - }); - - AddNested(end); - - foreach (var tick in s.Ticks) - { - var droplet = new DrawableDroplet(tick); - AddNested(droplet); + Fruit fruit = tick as Fruit; + if (fruit != null) + AddNested(new DrawableFruit(fruit)); } } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index fa19a6ff15..3ca0c8fbb6 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Objects TickDistance = scoringDistance / difficulty.SliderTickRate; } - public IEnumerable Ticks + public IEnumerable Ticks { get { @@ -53,8 +53,13 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - // temporary - while (tickDistance > 100) tickDistance /= 2; + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = StartTime, + X = X + }; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -66,8 +71,10 @@ namespace osu.Game.Rulesets.Catch.Objects if (d > length - minDistanceFromEnd) break; - var distanceProgress = d / length; - var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + var timeProgress = d / length; + var distanceProgress = reversed ? 1 - timeProgress : timeProgress; + + float tinyDroplet = 0; yield return new Droplet { @@ -81,6 +88,14 @@ namespace osu.Game.Rulesets.Catch.Objects })) }; } + + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = repeatStartTime + repeatDuration, + X = Curve.PositionAt(reversed ? 1 : 0).X + }; } } } From 0b282a49bd2b6f4145ea53d8738f4cec4486c6b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:11:29 +0900 Subject: [PATCH 56/90] Add tiny droplet support --- .../Objects/Drawable/DrawableDroplet.cs | 4 +- .../Objects/Drawable/DrawableJuiceStream.cs | 7 +++ .../Objects/JuiceStream.cs | 53 +++++++++++++++---- .../Objects/TinyDroplet.cs | 9 ++++ .../osu.Game.Rulesets.Catch.csproj | 1 + 5 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index aedef33cfd..fd48f11a3f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Size = new Vector2(Pulp.PULP_SIZE); - AccentColour = Color4.Green; + AccentColour = h.ComboColour; Masking = false; } @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = new Pulp { AccentColour = AccentColour, - Scale = new Vector2(0.6f), + Scale = new Vector2(0.8f), }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index fe54397d18..19abf243b3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -28,6 +28,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable foreach (CatchBaseHit tick in s.Ticks) { + TinyDroplet tiny = tick as TinyDroplet; + if (tiny != null) + { + AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); + continue; + } + Droplet droplet = tick as Droplet; if (droplet != null) AddNested(new DrawableDroplet(droplet)); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 3ca0c8fbb6..957a6e69ea 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -11,6 +11,8 @@ using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; +using osu.Framework.Lists; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -45,7 +47,10 @@ namespace osu.Game.Rulesets.Catch.Objects { get { - if (TickDistance == 0) yield break; + SortedList ticks = new SortedList((a, b) => a.StartTime.CompareTo(b.StartTime)); + + if (TickDistance == 0) + return ticks; var length = Curve.Distance; var tickDistance = Math.Min(TickDistance, length); @@ -53,13 +58,15 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - yield return new Fruit + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = StartTime, X = X - }; + }); + + double lastTickTime = StartTime; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -74,11 +81,11 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - float tinyDroplet = 0; - - yield return new Droplet + lastTickTime = repeatStartTime + timeProgress * repeatDuration; + ticks.Add(new Droplet { - StartTime = repeatStartTime + timeProgress * repeatDuration, + StartTime = lastTickTime, + ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, Samples = new SampleInfoList(Samples.Select(s => new SampleInfo { @@ -86,17 +93,41 @@ namespace osu.Game.Rulesets.Catch.Objects Name = @"slidertick", Volume = s.Volume })) - }; + }); } - yield return new Fruit + double tinyTickInterval = (tickDistance / length) * repeatDuration; + while (tinyTickInterval > 100) + tinyTickInterval /= 2; + + for (double t = 0; t < repeatDuration; t += tinyTickInterval) + { + double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration; + + ticks.Add(new TinyDroplet + { + StartTime = repeatStartTime + t, + ComboColour = ComboColour, + X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }); + } + + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = repeatStartTime + repeatDuration, - X = Curve.PositionAt(reversed ? 1 : 0).X - }; + X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH + }); } + + return ticks; } } diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs new file mode 100644 index 0000000000..231f3d5361 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs @@ -0,0 +1,9 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class TinyDroplet : Droplet + { + } +} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 906b7d663a..ba2c7a5f2e 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -61,6 +61,7 @@ + From 744d548738b92997f60b249413c3c431c25d6513 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:28:10 +0900 Subject: [PATCH 57/90] Add missing licence header --- osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 6a19bfa69a..00ddd365e3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -1,4 +1,7 @@ -using osu.Framework.Extensions.Color4Extensions; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 82b333740d5d65d637c86bfe57ab8735514f6c58 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 11 Oct 2017 15:20:23 +0300 Subject: [PATCH 58/90] Apply suggestions --- osu.Game/Overlays/Profile/ProfileHeader.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 742e865140..3814fdcc18 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -120,15 +120,13 @@ namespace osu.Game.Overlays.Profile } } }, - new LinkFlowContainer.BrowserLinkText + new LinkFlowContainer.ProfileLink(user) { - Text = user.Username, - Url = $@"https://osu.ppy.sh/users/{user.Id}", - TextSize = 30, - Font = @"Exo2.0-RegularItalic", Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Y = -48 + Y = -48, + TextSize = 30, + Font = @"Exo2.0-RegularItalic", }, countryFlag = new DrawableFlag(user.Country?.FlagName) { @@ -541,9 +539,15 @@ namespace osu.Game.Overlays.Profile } } - public class BrowserLinkText : LinkText, IHasTooltip + public class ProfileLink : LinkText, IHasTooltip { public string TooltipText => "View Profile in Browser"; + + public ProfileLink(User user) + { + Text = user.Username; + Url = $@"https://osu.ppy.sh/users/{user.Id}"; + } } } } From 4a4c01f2215f59be580e112c01919a412589f0a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:51:16 +0900 Subject: [PATCH 59/90] Fix CI problems --- .../Objects/Drawable/DrawableDroplet.cs | 1 - .../Objects/Drawable/DrawableJuiceStream.cs | 1 - osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 7 ++----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fd48f11a3f..2b2a8e7f8d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19abf243b3..afda91d0b4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -4,7 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; -using OpenTK.Graphics; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 957a6e69ea..f49799970d 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -12,7 +12,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; using osu.Framework.Lists; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -66,8 +65,6 @@ namespace osu.Game.Rulesets.Catch.Objects X = X }); - double lastTickTime = StartTime; - for (var repeat = 0; repeat < RepeatCount; repeat++) { var repeatStartTime = StartTime + repeat * repeatDuration; @@ -81,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - lastTickTime = repeatStartTime + timeProgress * repeatDuration; + var lastTickTime = repeatStartTime + timeProgress * repeatDuration; ticks.Add(new Droplet { StartTime = lastTickTime, @@ -96,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects }); } - double tinyTickInterval = (tickDistance / length) * repeatDuration; + double tinyTickInterval = tickDistance / length * repeatDuration; while (tinyTickInterval > 100) tinyTickInterval /= 2; From 6fbf52c3eb45a5ebcc48331efa882851c3cd4aa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:32:18 +0900 Subject: [PATCH 60/90] Remove unused usings --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 -- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 +- osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs | 1 - osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 5999241f61..c662341f20 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.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; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index f4795452d5..a64f139e5a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, + Depth = float.MaxValue }); Content.AutoSizeAxes = Axes.None; diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 40d617d2ea..00547145cd 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index c87be7e4b8..fc21b86c5d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual From e12fa4943609ff0b379878a819292606481e90be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:00 +0900 Subject: [PATCH 61/90] Integrate timeline into Compose --- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 2fe40dd010..2349c261cf 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Screens.Edit.Screens.Compose { @@ -13,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public Compose() { + ScrollableTimeline timeline; Children = new[] { new Container @@ -31,11 +33,22 @@ namespace osu.Game.Screens.Edit.Screens.Compose { Name = "Content", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 17, Vertical = 10 } + Padding = new MarginPadding { Horizontal = 17, Vertical = 10 }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 115 }, + Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + } + } } } } }; + + timeline.Beatmap.BindTo(Beatmap); } } } From 2844764e3c86a0b0acac92c133d97fedaf50aaa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:45 +0900 Subject: [PATCH 62/90] Hit Objects/Hit Sounds -> Hitobjects/Hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c662341f20..4c50dd4564 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -58,8 +58,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hit Objects" }, - new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Hitobjects" }, + new OsuCheckbox { LabelText = "Hitsounds" }, new OsuCheckbox { LabelText = "Waveform" } } } From de8f9325a3ed68cfc2888607a037318a37789a21 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 16:10:14 +0900 Subject: [PATCH 63/90] Implement TimelineButton and use for the magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 24 ++++------- .../Compose/Timeline/TimelineButton.cs | 42 +++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 2 +- osu.Game/osu.Game.csproj | 1 + 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 4c50dd4564..c1959f367b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -76,27 +76,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new FillFlowContainer + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 30), + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new SpriteIcon + new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_plus, - Colour = OsuColour.FromHex("555") - }, - new SpriteIcon - { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_minus, - Colour = OsuColour.FromHex("555") + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Icon = FontAwesome.fa_search_minus }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs new file mode 100644 index 0000000000..fc657325a4 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class TimelineButton : CompositeDrawable + { + public Action Action; + public readonly BindableBool Enabled = new BindableBool(true); + + public FontAwesome Icon + { + get { return button.Icon; } + set { button.Icon = value; } + } + + private readonly IconButton button; + + public TimelineButton() + { + InternalChild = button = new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + IconColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.FromHex("3A3A3A"), + FlashColour = OsuColour.FromHex("555"), + Action = () => Action?.Invoke() + }; + + button.Enabled.BindTo(Enabled); + Size = button.ButtonSize; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 00547145cd..02c32dfa56 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b0f8d8fac2..c054bf7b4e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,6 +275,7 @@ + From 78f2037d84391e75325ad418911f59ef2a185fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 09:42:06 +0200 Subject: [PATCH 64/90] Remove now obsolete RatioAdjust --- osu.Game/Graphics/Processing/RatioAdjust.cs | 27 --------------------- osu.Game/OsuGameBase.cs | 3 +-- osu.Game/osu.Game.csproj | 1 - 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 osu.Game/Graphics/Processing/RatioAdjust.cs diff --git a/osu.Game/Graphics/Processing/RatioAdjust.cs b/osu.Game/Graphics/Processing/RatioAdjust.cs deleted file mode 100644 index 640814d8e1..0000000000 --- a/osu.Game/Graphics/Processing/RatioAdjust.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Graphics.Containers; -using OpenTK; -using osu.Framework.Graphics; - -namespace osu.Game.Graphics.Processing -{ - internal class RatioAdjust : Container - { - public RatioAdjust() - { - RelativeSizeAxes = Axes.Both; - } - - protected override void Update() - { - base.Update(); - Vector2 parent = Parent.DrawSize; - - Scale = new Vector2(Math.Min(parent.Y / 768f, parent.X / 1024f)); - Size = new Vector2(1 / Scale.X); - } - } -} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e7bfa8a76..93eb1d76df 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; -using osu.Game.Graphics.Processing; using osu.Game.Online.API; using SQLite.Net; using osu.Framework.Graphics.Performance; @@ -186,7 +185,7 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - base.Content.Add(new RatioAdjust + base.Content.Add(new DrawSizePreservingFillContainer { Children = new Drawable[] { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 81f360f640..b7bb7de9e3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -312,7 +312,6 @@ - From 881eeaa650f9598e8055beddfa2afe928353654d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 16:57:05 +0900 Subject: [PATCH 65/90] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 07e84f60b0..31754e8fd0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 07e84f60b0d2ee443f366cb2e34bf25b680983dd +Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 From 4586877239ef234a7c3c1062c201fa9fde7521ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:31:21 +0900 Subject: [PATCH 66/90] Implement magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 9 ++++-- .../Timeline/ScrollingTimelineContainer.cs | 30 +++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c1959f367b..14c4f2d369 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -85,12 +85,17 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton + { + Icon = FontAwesome.fa_search_plus, + Action = () => timelineContainer.Zoom++ + }, new TimelineButton { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Icon = FontAwesome.fa_search_minus + Icon = FontAwesome.fa_search_minus, + Action = () => timelineContainer.Zoom-- }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a64f139e5a..209f0c9300 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -90,23 +90,43 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return; zoom = value; + // Make the zoom target default to the center of the graph if it hasn't been set + if (relativeContentZoomTarget == null) + relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X; + if (localZoomTarget == null) + localZoomTarget = DrawSize.X / 2; + Content.ResizeWidthTo(Zoom); + + // Update the scroll position to focus on the zoom target + float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value; + ScrollTo(scrollPos, false); + + relativeContentZoomTarget = null; + localZoomTarget = null; } } + /// + /// Zoom target as a relative position in the space. + /// + private float? relativeContentZoomTarget; + + /// + /// Zoom target as a position in our local space. + /// + private float? localZoomTarget; + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; Zoom += state.Mouse.WheelDelta; - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - return true; } } From 3c35a7a6ae5640fda75ce62f77f320e7ce59d676 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:37:40 +0900 Subject: [PATCH 67/90] graph -> waveform --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 209f0c9300..00b7e52e27 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -16,14 +16,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public readonly Bindable Beatmap = new Bindable(); - private readonly BeatmapWaveformGraph graph; + private readonly BeatmapWaveformGraph waveform; public ScrollingTimelineContainer() : base(Direction.Horizontal) { Masking = true; - Add(graph = new BeatmapWaveformGraph + Add(waveform = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.AutoSizeAxes = Axes.None; Content.RelativeSizeAxes = Axes.Both; - graph.Beatmap.BindTo(Beatmap); + waveform.Beatmap.BindTo(Beatmap); } private float minZoom = 1; From db672becbc19558b70645de20c9f59947ead1fa2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:50:51 +0900 Subject: [PATCH 68/90] Implement waveform checkbox --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 6 +++++- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 14c4f2d369..bf1237f1f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { new Box @@ -60,7 +61,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { new OsuCheckbox { LabelText = "Hitobjects" }, new OsuCheckbox { LabelText = "Hitsounds" }, - new OsuCheckbox { LabelText = "Waveform" } + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } } @@ -106,7 +107,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + waveformCheckbox.Current.Value = true; + timelineContainer.Beatmap.BindTo(Beatmap); + timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } protected override void Update() diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 00b7e52e27..a15db3d0df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); private readonly BeatmapWaveformGraph waveform; @@ -34,6 +35,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.RelativeSizeAxes = Axes.Both; waveform.Beatmap.BindTo(Beatmap); + WaveformVisible.ValueChanged += waveformVisibilityChanged; } private float minZoom = 1; @@ -129,5 +131,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } + + private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From 5ccfc1918e1a89a1639e016759e9c7b72ad29b4c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:51:01 +0900 Subject: [PATCH 69/90] Hook up more bindables for hitobjects/hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index bf1237f1f7..c64b223fa1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox hitObjectsCheckbox; + OsuCheckbox hitSoundsCheckbox; OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { @@ -59,8 +61,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hitobjects" }, - new OsuCheckbox { LabelText = "Hitsounds" }, + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } @@ -107,6 +109,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + hitObjectsCheckbox.Current.Value = true; + hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; timelineContainer.Beatmap.BindTo(Beatmap); diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a15db3d0df..c1bf2c3f57 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable HitObjectsVisible = new Bindable(); + public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); From a5817e6e75f803b50886b28d348fb33d53363088 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:23 +0900 Subject: [PATCH 70/90] Add a way to change the IconButton icon colour --- osu.Game/Graphics/UserInterface/IconButton.cs | 21 +++++++++++++++++-- osu.Game/Tests/Visual/TestCaseIconButton.cs | 12 +++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index d58f5797a3..afffd930ef 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -27,13 +27,28 @@ namespace osu.Game.Graphics.UserInterface set { flashColour = value; } } + private Color4? iconColour; /// /// The icon colour. This does not affect . /// public Color4 IconColour { - get { return icon.Colour; } - set { icon.Colour = value; } + get { return iconColour ?? Color4.White; } + set + { + iconColour = value; + icon.Colour = value; + } + } + + private Color4? iconHoverColour; + /// + /// The icon colour while the is hovered. + /// + public Color4 IconHoverColour + { + get { return iconHoverColour ?? IconColour; } + set { iconHoverColour = value; } } private Color4? hoverColour; @@ -133,12 +148,14 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(InputState state) { hover.FadeIn(500, Easing.OutQuint); + icon.FadeColour(IconHoverColour, 500, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { hover.FadeOut(500, Easing.OutQuint); + icon.FadeColour(IconColour, 500, Easing.OutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs index bec8f8314b..acde9df4a9 100644 --- a/osu.Game/Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -25,14 +25,18 @@ namespace osu.Game.Tests.Visual Children = new[] { new NamedIconButton("No change", new IconButton()), - new NamedIconButton("Green colours", new IconButton + new NamedIconButton("Background colours", new IconButton { - IconColour = Color4.LightGreen, FlashColour = Color4.DarkGreen, - HoverColour = Color4.Green + HoverColour = Color4.Green, }), new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), - new NamedIconButton("Unchanging size", new IconButton(), false) + new NamedIconButton("Unchanging size", new IconButton(), false), + new NamedIconButton("Icon colours", new IconButton + { + IconColour = Color4.Green, + IconHoverColour = Color4.Red + }) } }; } From a6901c0a2714e134608afbe9453a43abf1cec5f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:36 +0900 Subject: [PATCH 71/90] Change TimelineButton icon colour to white when hovered --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index fc657325a4..6fad1e5bb5 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,6 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Anchor = Anchor.Centre, Origin = Anchor.Centre, IconColour = OsuColour.FromHex("555"), + IconHoverColour = Color4.White, HoverColour = OsuColour.FromHex("3A3A3A"), FlashColour = OsuColour.FromHex("555"), Action = () => Action?.Invoke() From 1b031ca3280d104dadf9543ebf389e2719185b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:28:26 +0900 Subject: [PATCH 72/90] Fix potential read from empty queue in SPM counter --- .../Objects/Drawables/Pieces/SpinnerSpmCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index c079d3343b..ebe978f659 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces if (records.Count > 0) { var record = records.Peek(); - while (Time.Current - records.Peek().Time > spm_count_duration) + while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration) record = records.Dequeue(); SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } From ab623903367b74d2e30032fe5b04d61c6477774b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:32:39 +0900 Subject: [PATCH 73/90] Make TimelineButtons combined take up the full height of the timeline --- .../Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Edit/Screens/Compose/Timeline/TimelineButton.cs | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c64b223fa1..846a0d09f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -79,17 +79,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new Container + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, - Padding = new MarginPadding { Vertical = 5 }, + Masking = true, Children = new[] { new TimelineButton { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_plus, Action = () => timelineContainer.Zoom++ }, @@ -97,6 +99,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_minus, Action = () => timelineContainer.Zoom-- }, diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 6fad1e5bb5..8eec53c85f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -38,7 +39,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; button.Enabled.BindTo(Enabled); - Size = button.ButtonSize; + Width = button.ButtonSize.X; + } + + protected override void Update() + { + base.Update(); + + button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight); } } } From d9bf465b9c5a99b6c98dd323825461f3ef1c1c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 11:49:10 +0200 Subject: [PATCH 74/90] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..f1cda4873e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit f1cda4873eabc778afa323483e762491ee47f297 From 4d78a0492c78609bbee85ac78d410b55c8678951 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 19:15:59 +0900 Subject: [PATCH 75/90] Make creatorUsername a property so it is correctly deserialised --- osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index 470e13ea7b..d216b093ee 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -51,7 +51,7 @@ namespace osu.Game.Online.API.Requests private int onlineId { get; set; } [JsonProperty(@"creator")] - private string creatorUsername; + private string creatorUsername { get; set; } [JsonProperty(@"user_id")] private long creatorId = 1; From 8a5e25ce4b6401b86782415351879c64269f9d71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:50:12 +0900 Subject: [PATCH 76/90] Simplify waveform construction --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..c5235f4ecf 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit c5235f4ecfe933c04cbb2ee17adc714b9194fe0a diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index ad837b0e5b..a998b3eec3 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -574,15 +574,7 @@ namespace osu.Game.Beatmaps catch { return new TrackVirtual(); } } - protected override Waveform GetWaveform() - { - try - { - var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); - return trackData == null ? new Waveform() : new Waveform(trackData); - } - catch { return new Waveform(); } - } + protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile))); } /// From 70c55b23f4edecb0351a1e36afde330205a525ec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 20:30:15 +0900 Subject: [PATCH 77/90] Remove references to CodeAnalysisRulesets Having these produce warnings under certain compile environments. --- osu-framework | 2 +- osu.Game/osu.Game.csproj | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/osu-framework b/osu-framework index f1cda4873e..b43aecdce9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f1cda4873eabc778afa323483e762491ee47f297 +Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b7bb7de9e3..f14b441960 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -57,7 +57,6 @@ false AnyCPU true - AllRules.ruleset false false false @@ -77,7 +76,6 @@ false AnyCPU true - AllRules.ruleset false false @@ -103,7 +101,6 @@ false 6 prompt - AllRules.ruleset --tests false From fb8d8ec5524861f2ad7d96edd936a6b497c24bff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 21:26:25 +0900 Subject: [PATCH 78/90] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b43aecdce9..255b94f5dd 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 +Subproject commit 255b94f5dde0188db1a5b37daf9649659e2b8366 From 37b88d834e2584cb8f6aaeca89124300057ccd4f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:10:37 +0900 Subject: [PATCH 79/90] Adjust padding slightly --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 846a0d09f7..81beb4a4de 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Y, Width = 160, - Padding = new MarginPadding { Horizontal = 25 }, + Padding = new MarginPadding { Horizontal = 15 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 4), Children = new[] From 37fc69b9f71161088f3238cebbc5d90ef1fed5e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:02 +0900 Subject: [PATCH 80/90] Set a default zoom level that isn't the whole track --- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index c1bf2c3f57..47a77090b2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -38,6 +38,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; + + Zoom = 10; } private float minZoom = 1; From c0d64bf409b1e7afb9868a8040459d7e1e30fa21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:29 +0900 Subject: [PATCH 81/90] Use Gray instead of FromHex for grays --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 8eec53c85f..0c6fc5d133 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -31,10 +31,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, - IconColour = OsuColour.FromHex("555"), + IconColour = OsuColour.Gray(0.35f), IconHoverColour = Color4.White, - HoverColour = OsuColour.FromHex("3A3A3A"), - FlashColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.Gray(0.25f), + FlashColour = OsuColour.Gray(0.5f), Action = () => Action?.Invoke() }; From bb6b656ec688b6139bb5923d743e842949129766 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:27:22 +0900 Subject: [PATCH 82/90] Fix code review issues --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 4 +--- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index cffb2981bf..4c28a9d021 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -12,14 +12,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : DrawableCatchHitObject { - private const float pulp_size = 20; - public DrawableFruit(Fruit h) : base(h) { Origin = Anchor.Centre; - Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); + Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index f49799970d..6462f6f6a8 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects public class JuiceStream : CatchBaseHit, IHasCurve { /// - /// Scoring distance with a speed-adjusted beat length of 1 second. + /// Positional distance that results in a duration of one second, before any speed adjustments. /// private const float base_scoring_distance = 100; diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index f920f97790..363c330d3d 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,8 +15,6 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; - public double Scale = 1; - public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; @@ -202,4 +200,4 @@ namespace osu.Game.Rulesets.Objects return interpolateVertices(indexOfDistance(d), d) + Offset; } } -} \ No newline at end of file +} From abf54180800e6e207ba8af5da5cea91dbff1a0f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 14:06:34 +0900 Subject: [PATCH 83/90] Apply some renames and refactoring of loading logic Reduced publicly facing properties where possible. Also fixes a potentially bad state issue when the beatmapset was changed while a load was in progress. --- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 4 +- osu.Game/Overlays/Direct/PlayButton.cs | 79 +++++++++++-------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index d040c89a91..f77a1f4a0a 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -30,8 +30,8 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapSetInfo BeatmapSet { - get { return playButton.SetInfo; } - set { playButton.SetInfo = value; } + get { return playButton.BeatmapSet; } + set { playButton.BeatmapSet = value; } } public PreviewButton() diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 9ccce134d8..a98681234a 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -20,16 +20,17 @@ namespace osu.Game.Overlays.Direct public readonly Bindable Playing = new Bindable(); public Track Preview { get; private set; } - private BeatmapSetInfo setInfo; - public BeatmapSetInfo SetInfo + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet { - get { return setInfo; } + get { return beatmapSet; } set { - if (value == setInfo) return; - setInfo = value; + if (value == beatmapSet) return; + beatmapSet = value; Playing.Value = false; + trackLoader = null; Preview = null; } } @@ -41,13 +42,10 @@ namespace osu.Game.Overlays.Direct private const float transition_duration = 500; - private bool loading; - public bool Loading + private bool loading { - get { return loading; } set { - loading = value; if (value) { loadingAnimation.Show(); @@ -63,7 +61,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(BeatmapSetInfo setInfo = null) { - SetInfo = setInfo; + BeatmapSet = setInfo; AddRange(new Drawable[] { audioWrapper = new Container(), @@ -78,10 +76,12 @@ namespace osu.Game.Overlays.Direct loadingAnimation = new LoadingAnimation(), }); - Playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; - Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); - - Playing.ValueChanged += updatePreviewTrack; + Playing.ValueChanged += playing => + { + icon.Icon = playing ? FontAwesome.fa_pause : FontAwesome.fa_play; + icon.FadeColour(playing || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + updatePreviewTrack(playing); + }; } [BackgroundDependencyLoader] @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!Playing.Value) + if (!Playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } @@ -113,35 +113,25 @@ namespace osu.Game.Overlays.Direct { base.Update(); - if(Preview?.HasCompleted ?? false) + if (Preview?.HasCompleted ?? false) { Playing.Value = false; Preview = null; } } - private void updatePreviewTrack(bool newValue) + private void updatePreviewTrack(bool playing) { - if (newValue) + if (playing) { if (Preview == null) { - Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") - { - OnLoadComplete = d => - { - Loading = false; - Preview = (d as AudioLoadWrapper)?.Preview; - Playing.TriggerChange(); - }, - }); - } - else - { - Preview.Seek(0); - Preview.Start(); + beginAudioLoad(); + return; } + + Preview.Seek(0); + Preview.Start(); } else { @@ -149,13 +139,32 @@ namespace osu.Game.Overlays.Direct } } - private class AudioLoadWrapper : Drawable + private TrackLoader trackLoader; + + private void beginAudioLoad() + { + if (trackLoader != null) return; + + Add(new AsyncLoadWrapper(trackLoader = new TrackLoader($"https://b.ppy.sh/preview/{BeatmapSet.OnlineBeatmapSetID}.mp3") + { + OnLoadComplete = d => + { + // we may have been replaced by another loader + if (trackLoader != d) return; + + Preview = (d as TrackLoader)?.Preview; + Playing.TriggerChange(); + }, + })); + } + + private class TrackLoader : Drawable { private readonly string preview; public Track Preview; - public AudioLoadWrapper(string preview) + public TrackLoader(string preview) { this.preview = preview; } From 5b16f5d3b53b64146839ec87d7fdfa2ce4ecec6f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 14:15:44 +0900 Subject: [PATCH 84/90] Remove unused field --- osu.Game/Overlays/Direct/PlayButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index a98681234a..32435a4873 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Direct private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; - private readonly Container audioWrapper; private const float transition_duration = 500; @@ -64,7 +63,6 @@ namespace osu.Game.Overlays.Direct BeatmapSet = setInfo; AddRange(new Drawable[] { - audioWrapper = new Container(), icon = new SpriteIcon { Anchor = Anchor.Centre, From 070aceef1e5a2876d4b5d53e91b38e3b125d62df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 17:03:31 +0900 Subject: [PATCH 85/90] Move font and text size to class ProfileLink class --- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 3814fdcc18..337d4fe253 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -125,8 +125,6 @@ namespace osu.Game.Overlays.Profile Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Y = -48, - TextSize = 30, - Font = @"Exo2.0-RegularItalic", }, countryFlag = new DrawableFlag(user.Country?.FlagName) { @@ -547,6 +545,8 @@ namespace osu.Game.Overlays.Profile { Text = user.Username; Url = $@"https://osu.ppy.sh/users/{user.Id}"; + Font = @"Exo2.0-RegularItalic"; + TextSize = 30; } } } From 146d800bda407e6b7ede5cda770374361c6a8a6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 19:02:50 +0900 Subject: [PATCH 86/90] Make weight nullable rather than using weird negative defaults --- .../Profile/Sections/Ranks/DrawableScore.cs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index 27df3fd0fa..a9eb562d2f 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -27,9 +27,9 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private readonly FillFlowContainer metadata; private readonly ModContainer modContainer; private readonly Score score; - private readonly double weight; + private readonly double? weight; - public DrawableScore(Score score, double weight = -1) + public DrawableScore(Score score, double? weight = null) { this.score = score; this.weight = weight; @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Width = 60, - Margin = new MarginPadding{ Right = 150 } + Margin = new MarginPadding { Right = 150 } } }; } @@ -88,11 +88,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks TextSize = 18, Font = "Exo2.0-BoldItalic", }); - if (weight != -1) + + if (weight.HasValue) { stats.Add(new OsuSpriteText { - Text = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", + Text = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.Value.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, @@ -100,6 +101,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Font = "Exo2.0-RegularItalic", }); } + stats.Add(new OsuSpriteText { Text = "accuracy: " + score.Accuracy.ToString("0.00%"), @@ -121,7 +123,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { new OsuSpriteText { - Current = locale.GetUnicodePreference($"{score.Beatmap.Metadata.TitleUnicode ?? score.Beatmap.Metadata.Title} [{score.Beatmap.Version}] ", $"{score.Beatmap.Metadata.Title ?? score.Beatmap.Metadata.TitleUnicode} [{score.Beatmap.Version}] "), + Current = locale.GetUnicodePreference( + $"{score.Beatmap.Metadata.TitleUnicode ?? score.Beatmap.Metadata.Title} [{score.Beatmap.Version}] ", + $"{score.Beatmap.Metadata.Title ?? score.Beatmap.Metadata.TitleUnicode} [{score.Beatmap.Version}] " + ), TextSize = 15, Font = "Exo2.0-SemiBoldItalic", }, @@ -156,7 +161,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private class ModIcon : Rulesets.UI.ModIcon, IHasTooltip { - public ModIcon(Mod mod) : base(mod) + public ModIcon(Mod mod) + : base(mod) { TooltipText = mod.Name; } From ead88224c5abe0cb4d281feb86f61b2ff8b42a99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 19:14:43 +0900 Subject: [PATCH 87/90] Move ModIcon tooltip to base implementation --- .../Profile/Sections/Ranks/DrawableScore.cs | 13 +------------ osu.Game/Rulesets/UI/ModIcon.cs | 7 ++++++- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index a9eb562d2f..cac06348a7 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -16,8 +16,8 @@ using System.Diagnostics; using osu.Framework.Localisation; using System.Globalization; using osu.Game.Rulesets.Scoring; -using osu.Framework.Graphics.Cursor; using System; +using osu.Game.Rulesets.UI; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -158,16 +158,5 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks yield return new Vector2(DrawWidth * i * (count == 1 ? 0 : 1f / (count - 1)), 0); } } - - private class ModIcon : Rulesets.UI.ModIcon, IHasTooltip - { - public ModIcon(Mod mod) - : base(mod) - { - TooltipText = mod.Name; - } - - public string TooltipText { get; } - } } } diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 47a39d4644..7f7068d341 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -6,13 +6,14 @@ using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using OpenTK; namespace osu.Game.Rulesets.UI { - public class ModIcon : Container + public class ModIcon : Container, IHasTooltip { private readonly SpriteIcon modIcon; private readonly SpriteIcon background; @@ -27,12 +28,16 @@ namespace osu.Game.Rulesets.UI private readonly ModType type; + public string TooltipText { get; } + public ModIcon(Mod mod) { if (mod == null) throw new ArgumentNullException(nameof(mod)); type = mod.Type; + TooltipText = mod.Name; + Children = new Drawable[] { background = new SpriteIcon From 7550b461e3bbc7733f17c1a7db16e91153a1db99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 19:57:59 +0900 Subject: [PATCH 88/90] Add individual beatmap set lookup request --- .../API/Requests/GetBeatmapSetRequest.cs | 17 ++++++++++ ...tsRequest.cs => GetBeatmapSetsResponse.cs} | 23 ------------- .../API/Requests/SearchBeatmapSetsRequest.cs | 32 +++++++++++++++++++ osu.Game/Overlays/DirectOverlay.cs | 4 +-- osu.Game/osu.Game.csproj | 4 ++- 5 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs rename osu.Game/Online/API/Requests/{GetBeatmapSetsRequest.cs => GetBeatmapSetsResponse.cs} (69%) create mode 100644 osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs new file mode 100644 index 0000000000..e0fdc9adf2 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs @@ -0,0 +1,17 @@ +// 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.Requests +{ + public class GetBeatmapSetRequest : APIRequest + { + private readonly int beatmapSetId; + + public GetBeatmapSetRequest(int beatmapSetId) + { + this.beatmapSetId = beatmapSetId; + } + + protected override string Target => $@"beatmapsets/{beatmapSetId}"; + } +} diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsResponse.cs similarity index 69% rename from osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs rename to osu.Game/Online/API/Requests/GetBeatmapSetsResponse.cs index d216b093ee..085563845d 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsResponse.cs @@ -5,34 +5,11 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Game.Beatmaps; -using osu.Game.Overlays; -using osu.Game.Overlays.Direct; using osu.Game.Rulesets; using osu.Game.Users; 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")] diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs new file mode 100644 index 0000000000..56858b3d56 --- /dev/null +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -0,0 +1,32 @@ +// 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 osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Overlays.Direct; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests +{ + public class SearchBeatmapSetsRequest : 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 SearchBeatmapSetsRequest(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}"; + } +} diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 71dc558b26..14110724ea 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -248,7 +248,7 @@ namespace osu.Game.Overlays }); } - private GetBeatmapSetsRequest getSetsRequest; + private SearchBeatmapSetsRequest getSetsRequest; private readonly Bindable currentQuery = new Bindable(); @@ -269,7 +269,7 @@ namespace osu.Game.Overlays if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return; - getSetsRequest = new GetBeatmapSetsRequest(currentQuery.Value ?? string.Empty, + getSetsRequest = new SearchBeatmapSetsRequest(currentQuery.Value ?? string.Empty, ((FilterControl)Filter).Ruleset.Value, Filter.DisplayStyleControl.Dropdown.Current.Value, Filter.Tabs.Current.Value); //todo: sort direction (?) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f56f7c188d..ebedf32da0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -263,6 +263,8 @@ + + @@ -370,7 +372,7 @@ - + From 15373c71b6b4474719567e671f52f40fc0ae784c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 19:58:25 +0900 Subject: [PATCH 89/90] Allow scores to open beatmap overlay Reshuffles depth of beatmap and profile overlays for now. --- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/BeatmapSetOverlay.cs | 22 +++++++++++++++++++ .../Profile/Sections/Ranks/DrawableScore.cs | 8 ++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 75a1d61371..d1baca68db 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -188,8 +188,8 @@ namespace osu.Game GetToolbarHeight = () => ToolbarOffset, Depth = -1 }, overlayContent.Add); - LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -2 }, mainContent.Add); - LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -3 }, mainContent.Add); + LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add); + LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, mainContent.Add); LoadComponentAsync(musicController = new MusicController { Depth = -4, diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 7a4c6338a1..a60429f737 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; @@ -11,7 +12,10 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.BeatmapSet; +using osu.Game.Rulesets; namespace osu.Game.Overlays { @@ -23,6 +27,9 @@ namespace osu.Game.Overlays private readonly Header header; private readonly Info info; + private APIAccess api; + private RulesetStore rulesets; + // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; @@ -75,6 +82,13 @@ namespace osu.Game.Overlays header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; } + [BackgroundDependencyLoader] + private void load(APIAccess api, RulesetStore rulesets) + { + this.api = api; + this.rulesets = rulesets; + } + protected override void PopIn() { base.PopIn(); @@ -93,6 +107,14 @@ namespace osu.Game.Overlays return true; } + public void ShowBeatmapSet(int beatmapSetId) + { + // todo: display the overlay while we are loading here. we need to support setting BeatmapSet to null for this to work. + var req = new GetBeatmapSetRequest(beatmapSetId); + req.Success += res => ShowBeatmapSet(res.ToBeatmapSet(rulesets)); + api.Queue(req); + } + public void ShowBeatmapSet(BeatmapSetInfo set) { header.BeatmapSet = info.BeatmapSet = set; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index cac06348a7..52b68e7b30 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Select.Leaderboards; using System.Linq; -using System.Diagnostics; using osu.Framework.Localisation; using System.Globalization; using osu.Game.Rulesets.Scoring; @@ -78,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks } [BackgroundDependencyLoader] - private void load(OsuColour colour, LocalisationEngine locale) + private void load(OsuColour colour, LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay) { stats.Add(new OsuSpriteText { @@ -115,7 +114,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks metadata.Add(new OsuHoverContainer { AutoSizeAxes = Axes.Both, - Action = () => Process.Start($"https://osu.ppy.sh/beatmaps/{score.Beatmap.OnlineBeatmapID}"), + Action = () => + { + if (score.Beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay.ShowBeatmapSet(score.Beatmap.OnlineBeatmapSetID.Value); + }, Child = new FillFlowContainer { AutoSizeAxes = Axes.Both, From c660957329c176bdf82c2b11c90aa799d7c7bab0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 20:29:19 +0900 Subject: [PATCH 90/90] Hide (most) profile sections that aren't populated yet --- osu.Game/Overlays/UserProfileOverlay.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 587c994540..e6c45f6826 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -92,12 +92,12 @@ namespace osu.Game.Overlays sections = new ProfileSection[] { new AboutSection(), - new RecentSection(), + //new RecentSection(), new RanksSection(), - new MedalsSection(), - new HistoricalSection(), - new BeatmapsSection(), - new KudosuSection() + //new MedalsSection(), + //new HistoricalSection(), + //new BeatmapsSection(), + //new KudosuSection() }; tabs = new ProfileTabControl {