From 1d3139d3c3b9c6f0da17e2ebf9b7f688c148b107 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 18:32:07 -0300 Subject: [PATCH 01/96] Basic layout. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 126 ++++++++++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 139 ++++++++++++++++ osu.Game/Overlays/OnlineBeatmapSet/Info.cs | 155 ++++++++++++++++++ osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 80 +++++++++ osu.Game/osu.Game.csproj | 3 + 6 files changed, 504 insertions(+) create mode 100644 osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/Header.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/Info.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSetOverlay.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs new file mode 100644 index 0000000000..c939bc002c --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -0,0 +1,126 @@ +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Rulesets; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseOnlineBeatmapSetOverlay : TestCase + { + public override string Description => @"view online beatmap sets"; + + private readonly OnlineBeatmapSetOverlay overlay; + + public TestCaseOnlineBeatmapSetOverlay() + { + Add(overlay = new OnlineBeatmapSetOverlay()); + } + + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + var r = rulesets.GetRuleset(3); + + AddStep(@"show lachryma", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + OnlineBeatmapSetID = 415886, + Metadata = new BeatmapMetadata + { + Title = @"Lachryma ", + Artist = @"Kaneko Chiharu", + Author = @"Fresh Chicken", + Source = @"SOUND VOLTEX III GRAVITY WARS", + Tags = @"sdvx grace the 5th kac original song contest konami bemani", + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Preview = @"https://b.ppy.sh/preview/415886.mp3", + PlayCount = 681380, + FavouriteCount = 356, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + OnlineBeatmapID = 901048, + StarDifficulty = 1.36, + Version = @"BASIC", + Ruleset = r, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 6.5f, + OverallDifficulty = 6.5f, + ApproachRate = 5, + }, + }, + new BeatmapInfo + { + OnlineBeatmapID = 901051, + StarDifficulty = 2.22, + Version = @"NOVICE", + Ruleset = r, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7, + OverallDifficulty = 7, + ApproachRate = 5, + }, + }, + new BeatmapInfo + { + OnlineBeatmapID = 901047, + StarDifficulty = 3.49, + Version = @"ADVANCED", + Ruleset = r, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7.5f, + OverallDifficulty = 7.5f, + ApproachRate = 5, + }, + }, + new BeatmapInfo + { + OnlineBeatmapID = 901049, + StarDifficulty = 4.24, + Version = @"EXHAUST", + Ruleset = r, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 8, + OverallDifficulty = 8, + ApproachRate = 5, + }, + }, + new BeatmapInfo + { + OnlineBeatmapID = 901050, + StarDifficulty = 901050, + Version = @"GRAVITY", + Ruleset = r, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 8.5f, + OverallDifficulty = 8.5f, + ApproachRate = 5, + }, + }, + }, + }); + }); + } + } +} diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 86268e6110..2c0ef1cbee 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -112,6 +112,7 @@ + diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs new file mode 100644 index 0000000000..f4adbc2497 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -0,0 +1,139 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class Header : Container + { + public Header(BeatmapSetInfo set) + { + RelativeSizeAxes = Axes.X; + Height = 400; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new DelayedLoadWrapper(new BeatmapSetCover(set) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + OnLoadComplete = d => + { + d.FadeInFromZero(400, Easing.Out); + }, + }) + { + RelativeSizeAxes = Axes.Both, + TimeBeforeLoad = 300 + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), + }, + }, + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.X_PADDING }, + Spacing = new Vector2(1f), + Children = new Drawable[] + { + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 42, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 35, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 110, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 115, + }, + }, + }, + }, + }; + } + + private class DetailBox : Container + { + private Container content; + protected override Container Content => content; + + public DetailBox() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 15 }, + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs new file mode 100644 index 0000000000..948d20b0ac --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs @@ -0,0 +1,155 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class Info : Container + { + private const float metadata_width = 225; + private const float spacing = 20; + + private readonly BeatmapSetInfo set; + + private readonly Box successRateBackground; + private readonly FillFlowContainer metadataFlow; + private readonly ScrollContainer descriptionScroll; + + public Info(BeatmapSetInfo set) + { + this.set = set; + + RelativeSizeAxes = Axes.X; + Height = 220; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 15, Horizontal = OnlineBeatmapSetOverlay.X_PADDING }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = metadata_width + OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing * 2 }, + Child = descriptionScroll = new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + }, + }, + new ScrollContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = metadata_width, + ScrollbarVisible = false, + Padding = new MarginPadding { Horizontal = 10 }, + Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing }, + Child = metadataFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, + }, + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, + Children = new[] + { + successRateBackground = new Box + { + RelativeSizeAxes = Axes.Both, + }, + }, + }, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + successRateBackground.Colour = colours.GrayE; + descriptionScroll.Child = new MetadataSection("Description", "", colours.Gray5); + metadataFlow.Children = new[] + { + new MetadataSection("Source", set.Metadata.Source, colours.Gray5), + new MetadataSection("Tags", set.Metadata.Tags, colours.BlueDark), + }; + } + + private class MetadataSection : FillFlowContainer + { + private readonly OsuSpriteText header; + + public MetadataSection(string title, string body, Color4 textColour) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + Spacing = new Vector2(5f); + + TextFlowContainer content; + Children = new Drawable[] + { + header = new OsuSpriteText + { + Font = @"Exo2.0-Bold", + TextSize = 14, + Text = title, + Margin = new MarginPadding { Top = 20 }, + }, + content = new TextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + }; + + content.AddText(body, t => + { + t.TextSize = 14; + t.Colour = textColour; + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + header.Colour = colours.Gray5; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs new file mode 100644 index 0000000000..4fae3cac35 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs @@ -0,0 +1,80 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays.OnlineBeatmapSet; + +namespace osu.Game.Overlays +{ + public class OnlineBeatmapSetOverlay : WaveOverlayContainer + { + public const float X_PADDING = 40; + public const float RIGHT_WIDTH = 275; + + private readonly ReverseChildIDFillFlowContainer scrollContent; + + public OnlineBeatmapSetOverlay() + { + FirstWaveColour = OsuColour.Gray(0.4f); + SecondWaveColour = OsuColour.Gray(0.3f); + ThirdWaveColour = OsuColour.Gray(0.2f); + FourthWaveColour = OsuColour.Gray(0.1f); + + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + RelativeSizeAxes = Axes.Both; + Width = 0.85f; + + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + + Child = new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + Child = scrollContent = new ReverseChildIDFillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, + }; + } + + protected override void PopIn() + { + base.PopIn(); + FadeEdgeEffectTo(0.25f, APPEAR_DURATION, Easing.In); + } + + protected override void PopOut() + { + base.PopOut(); + FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); + } + + public void ShowBeatmapSet(BeatmapSetInfo set) + { + scrollContent.Children = new Drawable[] + { + new Header(set), + new Info(set), + }; + + Show(); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..f3f67149fa 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -538,6 +538,9 @@ + + + From ecd6994d743eb718cc23d1ef0d62ab15878b0244 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 19:17:39 -0300 Subject: [PATCH 02/96] Added favourite/download buttons and author info. --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 22 ++ .../Overlays/OnlineBeatmapSet/AuthorInfo.cs | 83 +++++ osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 329 +++++++++++++++--- osu.Game/Overlays/OnlineBeatmapSet/Info.cs | 1 + 4 files changed, 384 insertions(+), 51 deletions(-) create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index e5a1984f50..40755b468f 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -1,7 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using Newtonsoft.Json; +using osu.Game.Users; namespace osu.Game.Beatmaps { @@ -10,6 +12,26 @@ namespace osu.Game.Beatmaps /// public class BeatmapSetOnlineInfo { + /// + /// The author of the beatmaps in this set. + /// + public User Author; + + /// + /// The date this beatmap set was submitted to the online listing. + /// + public DateTimeOffset Submitted { get; set; } + + /// + /// The date this beatmap set was ranked. + /// + public DateTimeOffset Ranked { get; set; } + + /// + /// The date this beatmap set was last updated. + /// + public DateTimeOffset LastUpdated { get; set; } + /// /// The different sizes of cover art for this beatmap set. /// diff --git a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs new file mode 100644 index 0000000000..af4566a3f8 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs @@ -0,0 +1,83 @@ +// 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 OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class AuthorInfo : Container + { + private const float height = 50; + + public AuthorInfo(BeatmapSetOnlineInfo info) + { + RelativeSizeAxes = Axes.X; + Height = height; + + Children = new Drawable[] + { + new UpdateableAvatar + { + Size = new Vector2(height), + CornerRadius = 3, + Masking = true, + User = info.Author, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Left = height + 5 }, + Children = new Drawable[] + { + new Field("made by", info.Author.Username, @"Exo2.0-RegularItalic"), + new Field("submitted on", info.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") + { + Margin = new MarginPadding { Top = 5 }, + }, + new Field(info.Ranked == null ? "last updated on " : "ranked on ", (info.Ranked == null ? info.Submitted : info.Ranked).ToString(@"MMM d, yyyy"), @"Exo2.0-Bold"), + }, + }, + }; + } + + private class Field : FillFlowContainer + { + public Field(string first, string second, string secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new OsuSpriteText + { + Text = $"{first} ", + TextSize = 13, + }, + new OsuSpriteText + { + Text = second, + TextSize = 13, + Font = secondFont, + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index f4adbc2497..35bd3bebdc 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -3,6 +3,8 @@ using OpenTK; using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -10,11 +12,19 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.OnlineBeatmapSet { public class Header : Container { + private const float tabs_height = 50; + + private readonly Box tabsBg; + public Header(BeatmapSetInfo set) { RelativeSizeAxes = Axes.X; @@ -32,76 +42,148 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { new Container { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + RelativeSizeAxes = Axes.X, + Height = tabs_height, + Children = new[] { - new Box + tabsBg = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - new DelayedLoadWrapper(new BeatmapSetCover(set) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fill, - OnLoadComplete = d => - { - d.FadeInFromZero(400, Easing.Out); - }, - }) - { - RelativeSizeAxes = Axes.Both, - TimeBeforeLoad = 300 - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), }, }, }, - new FillFlowContainer + new Container { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.X_PADDING }, - Spacing = new Vector2(1f), + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = tabs_height }, Children = new Drawable[] { - new DetailBox + new Container { - Child = new Container + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 42, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new DelayedLoadWrapper(new BeatmapSetCover(set) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + OnLoadComplete = d => + { + d.FadeInFromZero(400, Easing.Out); + }, + }) + { + RelativeSizeAxes = Axes.Both, + TimeBeforeLoad = 300 + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), + }, }, }, - new DetailBox + new Container { - Child = new Container + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = OnlineBeatmapSetOverlay.X_PADDING }, + Child = new FillFlowContainer { - RelativeSizeAxes = Axes.X, - Height = 35, + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new Container + { + Name = @"beatmap picker", + RelativeSizeAxes = Axes.X, + Height = 113, + }, + new OsuSpriteText + { + Text = set.Metadata.Title, + Font = @"Exo2.0-BoldItalic", + TextSize = 37, + }, + new OsuSpriteText + { + Text = set.Metadata.Artist, + Font = @"Exo2.0-SemiBoldItalic", + TextSize = 25, + }, + new Container + { + Name = "mapper", + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 20 }, + Child = new AuthorInfo(set.OnlineInfo), + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + Height = 45, + Spacing = new Vector2(5f), + Margin = new MarginPadding { Top = 10 }, + Children = new Button[] + { + new FavouriteButton(), + new DownloadButton("Download", ""), + new DownloadButton("osu!direct", ""), + }, + }, + }, }, }, - new DetailBox + new FillFlowContainer { - Child = new Container + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.X_PADDING }, + Spacing = new Vector2(1f), + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 110, - }, - }, - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 115, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 42, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 35, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 110, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 115, + }, + }, }, }, }, @@ -109,6 +191,151 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + tabsBg.Colour = colours.Gray3; + } + + private class Button : OsuClickableContainer + { + private readonly Container content; + + protected override Container Content => content; + + public Button() + { + CornerRadius = 3; + Masking = true; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"094c5f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"0f7c9b"), + ColourDark = OsuColour.FromHex(@"094c5f"), + TriangleScale = 1.5f, + }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }; + } + } + + private class DownloadButton : Button + { + public DownloadButton(string title, string subtitle) + { + Width = 120; + RelativeSizeAxes = Axes.Y; + + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new[] + { + new OsuSpriteText + { + Text = title, + TextSize = 13, + Font = @"Exo2.0-Bold", + }, + new OsuSpriteText + { + Text = subtitle, + TextSize = 11, + Font = @"Exo2.0-Bold", + }, + }, + }, + new SpriteIcon + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Icon = FontAwesome.fa_download, + Size = new Vector2(16), + Margin = new MarginPadding { Right = 5 }, + }, + }, + }; + } + } + + private class FavouriteButton : Button + { + public readonly Bindable Favourited = new Bindable(); + + public FavouriteButton() + { + RelativeSizeAxes = Axes.Y; + + Container pink; + SpriteIcon icon; + Children = new Drawable[] + { + pink = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"9f015f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"cb2187"), + ColourDark = OsuColour.FromHex(@"9f015f"), + TriangleScale = 1.5f, + }, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_heart_o, + Size = new Vector2(18), + Shadow = false, + }, + }; + + Favourited.ValueChanged += value => + { + pink.FadeTo(value ? 1 : 0, 200); + icon.Icon = value ? FontAwesome.fa_heart : FontAwesome.fa_heart_o; + }; + Action = () => Favourited.Value = !Favourited.Value; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Width = DrawHeight; + } + } + private class DetailBox : Container { private Container content; diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs index 948d20b0ac..b4c505b136 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs @@ -129,6 +129,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Font = @"Exo2.0-Bold", TextSize = 14, Text = title, + Shadow = false, Margin = new MarginPadding { Top = 20 }, }, content = new TextFlowContainer From cbd9c07aed87953ef07a5432179c5b05ca2853d9 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 9 Sep 2017 18:19:43 -0300 Subject: [PATCH 03/96] BeatmapPicker design. --- .../OnlineBeatmapSet/BeatmapPicker.cs | 218 ++++++++++++++++++ osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 3 +- 2 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs new file mode 100644 index 0000000000..fa02754d80 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -0,0 +1,218 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class BeatmapPicker : Container + { + private const float tile_icon_padding = 7; + private const float tile_spacing = 2; + + private readonly OsuSpriteText version, starRating; + + public BeatmapPicker(BeatmapSetInfo set) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + FillFlowContainer tileContainer; + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + tileContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 10 }, + Spacing = new Vector2(5f), + Children = new[] + { + version = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + TextSize = 20, + Font = @"Exo2.0-Bold", + Text = "BASIC", + }, + starRating = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + TextSize = 13, + Font = @"Exo2.0-Bold", + Text = "Star Difficulty 1.36", + Margin = new MarginPadding { Bottom = 1 }, + }, + }, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10f), + Margin = new MarginPadding { Top = 5 }, + Children = new[] + { + new Statistic(FontAwesome.fa_play_circle, 682712), + new Statistic(FontAwesome.fa_heart, 357), + }, + }, + }, + }, + }; + + tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b) + { + OnHovered = beatmap => + { + }, + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + starRating.Colour = colours.Yellow; + } + + private class BeatmapTile : OsuClickableContainer + { + private const float transition_duration = 100; + private const float size = 52; + + private readonly BeatmapInfo beatmap; + + private readonly Container bg; + private readonly DifficultyIcon icon; + + public Action OnHovered; + + public BeatmapTile(BeatmapInfo beatmap) + { + this.beatmap = beatmap; + Size = new Vector2(size); + Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; + + Children = new Drawable[] + { + bg = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + }, + icon = new DifficultyIcon(beatmap) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(size - tile_icon_padding * 2), + Margin = new MarginPadding { Bottom = 1 }, + }, + }; + + fadeOut(); + } + + protected override bool OnHover(InputState state) + { + fadeIn(); + OnHovered?.Invoke(beatmap); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + fadeOut(); + } + + private void fadeIn() + { + bg.FadeIn(transition_duration); + icon.FadeIn(transition_duration); + } + + private void fadeOut() + { + bg.FadeOut(); + icon.FadeTo(0.7f, transition_duration); + } + } + + private class Statistic : FillFlowContainer + { + private readonly OsuSpriteText text; + + private int value; + public int Value + { + get { return value; } + set + { + this.value = value; + text.Text = Value.ToString(@"N0"); + } + } + + public Statistic(FontAwesome icon, int value = 0) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2f); + + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = icon, + Shadow = true, + Size = new Vector2(13), + }, + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = @"Exo2.0-SemiBoldItalic", + TextSize = 14, + }, + }; + + Value = value; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 35bd3bebdc..1e6b81ae1f 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -102,9 +102,9 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { new Container { - Name = @"beatmap picker", RelativeSizeAxes = Axes.X, Height = 113, + Child = new BeatmapPicker(set), }, new OsuSpriteText { @@ -120,7 +120,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, new Container { - Name = "mapper", RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Top = 20 }, From aa9dfcc082da5c372dd093b7055ff5fca6786ef0 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 9 Sep 2017 19:05:22 -0300 Subject: [PATCH 04/96] BeatmapPicker logic. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 13 +++- .../OnlineBeatmapSet/BeatmapPicker.cs | 59 +++++++++++++++---- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index c939bc002c..2bbe6ea952 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -1,9 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Rulesets; +using osu.Game.Users; namespace osu.Desktop.VisualTests.Tests { @@ -41,6 +43,13 @@ namespace osu.Desktop.VisualTests.Tests Preview = @"https://b.ppy.sh/preview/415886.mp3", PlayCount = 681380, FavouriteCount = 356, + Submitted = new DateTime(2016, 2, 10), + Ranked = new DateTime(2016, 6, 19), + Author = new User + { + Username = @"Fresh Chicken", + Id = 3984370, + }, Covers = new BeatmapSetOnlineCovers { Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778", @@ -107,7 +116,7 @@ namespace osu.Desktop.VisualTests.Tests new BeatmapInfo { OnlineBeatmapID = 901050, - StarDifficulty = 901050, + StarDifficulty = 5.26, Version = @"GRAVITY", Ruleset = r, Difficulty = new BeatmapDifficulty diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index fa02754d80..2a0e137a4e 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -6,6 +6,7 @@ using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -26,12 +27,14 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private readonly OsuSpriteText version, starRating; + public readonly Bindable Beatmap = new Bindable(); + public BeatmapPicker(BeatmapSetInfo set) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - FillFlowContainer tileContainer; + TilesFillFlowContainer tileContainer; Children = new Drawable[] { new FillFlowContainer @@ -41,11 +44,15 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Direction = FillDirection.Vertical, Children = new Drawable[] { - tileContainer = new FillFlowContainer + tileContainer = new TilesFillFlowContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, + OnLostHover = () => + { + showBeatmap(Beatmap.Value); + starRating.FadeOut(100); + }, }, new FillFlowContainer { @@ -60,7 +67,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Origin = Anchor.BottomLeft, TextSize = 20, Font = @"Exo2.0-Bold", - Text = "BASIC", }, starRating = new OsuSpriteText { @@ -68,7 +74,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Origin = Anchor.BottomLeft, TextSize = 13, Font = @"Exo2.0-Bold", - Text = "Star Difficulty 1.36", + Text = "Star Difficulty", + Alpha = 0, Margin = new MarginPadding { Bottom = 1 }, }, }, @@ -89,12 +96,19 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }; - tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b) + Beatmap.Value = set.Beatmaps.First(); + Beatmap.ValueChanged += showBeatmap; + tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b, Beatmap) { OnHovered = beatmap => { + showBeatmap(beatmap); + starRating.Text = string.Format("Star Difficulty {0:N2}", beatmap.StarDifficulty); + starRating.FadeIn(100); }, }); + + Beatmap.TriggerChange(); } [BackgroundDependencyLoader] @@ -103,21 +117,36 @@ namespace osu.Game.Overlays.OnlineBeatmapSet starRating.Colour = colours.Yellow; } + private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; + + private class TilesFillFlowContainer : FillFlowContainer + { + public Action OnLostHover; + + protected override void OnHoverLost(InputState state) + { + base.OnHoverLost(state); + OnLostHover?.Invoke(); + } + } + private class BeatmapTile : OsuClickableContainer { private const float transition_duration = 100; private const float size = 52; private readonly BeatmapInfo beatmap; + private readonly Bindable bindable = new Bindable(); private readonly Container bg; private readonly DifficultyIcon icon; public Action OnHovered; - public BeatmapTile(BeatmapInfo beatmap) + public BeatmapTile(BeatmapInfo beatmap, Bindable bindable) { this.beatmap = beatmap; + this.bindable.BindTo(bindable); Size = new Vector2(size); Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; @@ -143,7 +172,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }; - fadeOut(); + Action = () => this.bindable.Value = beatmap; + this.bindable.ValueChanged += bindable_ValueChanged; } protected override bool OnHover(InputState state) @@ -155,7 +185,16 @@ namespace osu.Game.Overlays.OnlineBeatmapSet protected override void OnHoverLost(InputState state) { - fadeOut(); + if (bindable.Value != beatmap) + fadeOut(); + } + + private void bindable_ValueChanged(BeatmapInfo value) + { + if (value == beatmap) + fadeIn(); + else + fadeOut(); } private void fadeIn() From 54172ac6adc4450c7abffbc444ed86800616d4e6 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 11 Sep 2017 01:21:53 -0300 Subject: [PATCH 05/96] Move header button and details components to own files. --- osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 85 +++++++ .../OnlineBeatmapSet/DownloadButton.cs | 59 +++++ .../OnlineBeatmapSet/FavouriteButton.cs | 71 ++++++ osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 211 +----------------- .../Overlays/OnlineBeatmapSet/HeaderButton.cs | 45 ++++ 5 files changed, 262 insertions(+), 209 deletions(-) create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/Details.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs new file mode 100644 index 0000000000..69a489d05a --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class Details : FillFlowContainer + { + public Details() + { + Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; + AutoSizeAxes = Axes.Y; + Spacing = new Vector2(1f); + + Children = new Drawable[] + { + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 42, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 35, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 110, + }, + }, + new DetailBox + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 115, + }, + }, + }; + } + + private class DetailBox : Container + { + private Container content; + protected override Container Content => content; + + public DetailBox() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 15 }, + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs new file mode 100644 index 0000000000..96f811ca55 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.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 OpenTK; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class DownloadButton : HeaderButton + { + public DownloadButton(string title, string subtitle) + { + Width = 120; + RelativeSizeAxes = Axes.Y; + + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new[] + { + new OsuSpriteText + { + Text = title, + TextSize = 13, + Font = @"Exo2.0-Bold", + }, + new OsuSpriteText + { + Text = subtitle, + TextSize = 11, + Font = @"Exo2.0-Bold", + }, + }, + }, + new SpriteIcon + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Icon = FontAwesome.fa_download, + Size = new Vector2(16), + Margin = new MarginPadding { Right = 5 }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs new file mode 100644 index 0000000000..140e2cd120 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs @@ -0,0 +1,71 @@ +// 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.Game.Graphics; +using osu.Game.Graphics.Backgrounds; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class FavouriteButton : HeaderButton + { + public readonly Bindable Favourited = new Bindable(); + + public FavouriteButton() + { + RelativeSizeAxes = Axes.Y; + + Container pink; + SpriteIcon icon; + Children = new Drawable[] + { + pink = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"9f015f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"cb2187"), + ColourDark = OsuColour.FromHex(@"9f015f"), + TriangleScale = 1.5f, + }, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_heart_o, + Size = new Vector2(18), + Shadow = false, + }, + }; + + Favourited.ValueChanged += value => + { + pink.FadeTo(value ? 1 : 0, 200); + icon.Icon = value ? FontAwesome.fa_heart : FontAwesome.fa_heart_o; + }; + Action = () => Favourited.Value = !Favourited.Value; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Width = DrawHeight; + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 1e6b81ae1f..cea497af8c 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -4,7 +4,6 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -13,8 +12,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.OnlineBeatmapSet @@ -131,7 +128,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Height = 45, Spacing = new Vector2(5f), Margin = new MarginPadding { Top = 10 }, - Children = new Button[] + Children = new HeaderButton[] { new FavouriteButton(), new DownloadButton("Download", ""), @@ -141,49 +138,11 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }, }, - new FillFlowContainer + new Details { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, - Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, - AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.X_PADDING }, - Spacing = new Vector2(1f), - Children = new Drawable[] - { - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 42, - }, - }, - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 35, - }, - }, - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 110, - }, - }, - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 115, - }, - }, - }, }, }, }, @@ -195,171 +154,5 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { tabsBg.Colour = colours.Gray3; } - - private class Button : OsuClickableContainer - { - private readonly Container content; - - protected override Container Content => content; - - public Button() - { - CornerRadius = 3; - Masking = true; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"094c5f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"0f7c9b"), - ColourDark = OsuColour.FromHex(@"094c5f"), - TriangleScale = 1.5f, - }, - content = new Container - { - RelativeSizeAxes = Axes.Both, - }, - }; - } - } - - private class DownloadButton : Button - { - public DownloadButton(string title, string subtitle) - { - Width = 120; - RelativeSizeAxes = Axes.Y; - - Child = new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 10 }, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new[] - { - new OsuSpriteText - { - Text = title, - TextSize = 13, - Font = @"Exo2.0-Bold", - }, - new OsuSpriteText - { - Text = subtitle, - TextSize = 11, - Font = @"Exo2.0-Bold", - }, - }, - }, - new SpriteIcon - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Icon = FontAwesome.fa_download, - Size = new Vector2(16), - Margin = new MarginPadding { Right = 5 }, - }, - }, - }; - } - } - - private class FavouriteButton : Button - { - public readonly Bindable Favourited = new Bindable(); - - public FavouriteButton() - { - RelativeSizeAxes = Axes.Y; - - Container pink; - SpriteIcon icon; - Children = new Drawable[] - { - pink = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"9f015f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"cb2187"), - ColourDark = OsuColour.FromHex(@"9f015f"), - TriangleScale = 1.5f, - }, - }, - }, - icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_heart_o, - Size = new Vector2(18), - Shadow = false, - }, - }; - - Favourited.ValueChanged += value => - { - pink.FadeTo(value ? 1 : 0, 200); - icon.Icon = value ? FontAwesome.fa_heart : FontAwesome.fa_heart_o; - }; - Action = () => Favourited.Value = !Favourited.Value; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - Width = DrawHeight; - } - } - - private class DetailBox : Container - { - private Container content; - protected override Container Content => content; - - public DetailBox() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - content = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 15 }, - }, - }; - } - } } } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs new file mode 100644 index 0000000000..4c46b9e56f --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs @@ -0,0 +1,45 @@ +// 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.Game.Graphics; +using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class HeaderButton : OsuClickableContainer + { + private readonly Container content; + + protected override Container Content => content; + + public HeaderButton() + { + CornerRadius = 3; + Masking = true; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"094c5f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"0f7c9b"), + ColourDark = OsuColour.FromHex(@"094c5f"), + TriangleScale = 1.5f, + }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} From 43fa314fe085179af36bc5823e123c9d7f3f2310 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 11 Sep 2017 02:48:48 -0300 Subject: [PATCH 06/96] Details and more data displaying. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 73 ++++++++++ osu.Game/Beatmaps/BeatmapOnlineInfo.cs | 17 +++ osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 10 ++ .../Overlays/OnlineBeatmapSet/BasicStats.cs | 124 ++++++++++++++++ .../OnlineBeatmapSet/BeatmapPicker.cs | 10 +- osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 54 +++++-- osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 31 +++- osu.Game/Overlays/OnlineBeatmapSet/Info.cs | 14 +- .../OnlineBeatmapSet/PreviewButton.cs | 137 ++++++++++++++++++ .../Overlays/OnlineBeatmapSet/SuccessRate.cs | 117 +++++++++++++++ osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 9 +- osu.Game/osu.Game.csproj | 11 +- 12 files changed, 581 insertions(+), 26 deletions(-) create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs create mode 100644 osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index 2bbe6ea952..2d26c6c518 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Beatmaps; @@ -45,6 +46,8 @@ namespace osu.Desktop.VisualTests.Tests FavouriteCount = 356, Submitted = new DateTime(2016, 2, 10), Ranked = new DateTime(2016, 6, 19), + Length = 118000, + BPM = 236, Author = new User { Username = @"Fresh Chicken", @@ -70,6 +73,20 @@ namespace osu.Desktop.VisualTests.Tests OverallDifficulty = 6.5f, ApproachRate = 5, }, + OnlineInfo = new BeatmapOnlineInfo + { + HasVideo = false, + CircleCount = 265, + SliderCount = 71, + PlayCount = 47906, + PassCount = 19899, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, }, new BeatmapInfo { @@ -84,6 +101,20 @@ namespace osu.Desktop.VisualTests.Tests OverallDifficulty = 7, ApproachRate = 5, }, + OnlineInfo = new BeatmapOnlineInfo + { + HasVideo = false, + CircleCount = 592, + SliderCount = 62, + PlayCount = 162021, + PassCount = 72116, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, }, new BeatmapInfo { @@ -98,6 +129,20 @@ namespace osu.Desktop.VisualTests.Tests OverallDifficulty = 7.5f, ApproachRate = 5, }, + OnlineInfo = new BeatmapOnlineInfo + { + HasVideo = false, + CircleCount = 1042, + SliderCount = 79, + PlayCount = 225178, + PassCount = 73001, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, }, new BeatmapInfo { @@ -112,6 +157,20 @@ namespace osu.Desktop.VisualTests.Tests OverallDifficulty = 8, ApproachRate = 5, }, + OnlineInfo = new BeatmapOnlineInfo + { + HasVideo = false, + CircleCount = 1352, + SliderCount = 69, + PlayCount = 131545, + PassCount = 42703, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, }, new BeatmapInfo { @@ -126,6 +185,20 @@ namespace osu.Desktop.VisualTests.Tests OverallDifficulty = 8.5f, ApproachRate = 5, }, + OnlineInfo = new BeatmapOnlineInfo + { + HasVideo = false, + CircleCount = 1730, + SliderCount = 115, + PlayCount = 117673, + PassCount = 24241, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, }, }, }); diff --git a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs index e8f40a7e07..c9794107ce 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs @@ -10,6 +10,23 @@ namespace osu.Game.Beatmaps /// public class BeatmapOnlineInfo { + /// + /// Whether or not this beatmap has a background video. + /// + public bool HasVideo { get; set; } + + /// + /// The amount of circles in this beatmap. + /// + [JsonProperty(@"count_circles")] + public int CircleCount { get; set; } + + /// + /// The amount of sliders in this beatmap. + /// + [JsonProperty(@"count_sliders")] + public int SliderCount { get; set; } + /// /// The amount of plays this beatmap has. /// diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 40755b468f..8009ea5b9e 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -44,6 +44,16 @@ namespace osu.Game.Beatmaps [JsonProperty(@"previewUrl")] public string Preview { get; set; } + /// + /// The length in milliseconds of this beatmap's song. + /// + public double Length { get; set; } + + /// + /// The beats per minute of this beatmap set's song. + /// + public double BPM { get; set; } + /// /// The amount of plays this beatmap set has. /// diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs new file mode 100644 index 0000000000..fa45a04b40 --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs @@ -0,0 +1,124 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class BasicStats : Container + { + private readonly Statistic length, bpm, circleCount, sliderCount; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); + sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); + } + } + + public BasicStats(BeatmapSetInfo set) + { + var statWidth = 0.25f; + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new[] + { + length = new Statistic(FontAwesome.fa_clock_o, "Length") + { + Width = statWidth, + Value = TimeSpan.FromMilliseconds(set.OnlineInfo.Length).ToString(@"m\:ss"), + }, + bpm = new Statistic(FontAwesome.fa_circle, "BPM") + { + Width = statWidth, + Value = set.OnlineInfo.BPM.ToString(@"0.##"), + }, + circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, + sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, + }, + }; + } + + private class Statistic : Container, IHasTooltip + { + private readonly string name; + private readonly OsuSpriteText value; + + public string TooltipText => name; + public string Value + { + get { return value.Text; } + set { this.value.Text = value; } + } + + public Statistic(FontAwesome icon, string name) + { + this.name = name; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_square, + Size = new Vector2(13), + Rotation = 45, + Colour = OsuColour.FromHex(@"441288"), + }, + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Icon = icon, + Size = new Vector2(13), + Colour = OsuColour.FromHex(@"f7dd55"), + Scale = new Vector2(0.8f), + }, + value = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 13, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Left = 10 }, + }, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + value.Colour = colour.Yellow; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 2a0e137a4e..3a1fe9bd07 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -107,8 +107,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet starRating.FadeIn(100); }, }); - - Beatmap.TriggerChange(); } [BackgroundDependencyLoader] @@ -117,6 +115,14 @@ namespace osu.Game.Overlays.OnlineBeatmapSet starRating.Colour = colours.Yellow; } + protected override void LoadComplete() + { + base.LoadComplete(); + + // done here so everything can bind in intialization and get the first trigger + Beatmap.TriggerChange(); + } + private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; private class TilesFillFlowContainer : FillFlowContainer diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs index 69a489d05a..300eb3a8e1 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -7,12 +7,32 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Screens.Select.Details; namespace osu.Game.Overlays.OnlineBeatmapSet { public class Details : FillFlowContainer { - public Details() + private readonly BasicStats basic; + private readonly AdvancedStats advanced; + private readonly UserRatings ratings; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + basic.Beatmap = advanced.Beatmap = Beatmap; + ratings.Metrics = Beatmap.Metrics; + } + } + + public Details(BeatmapSetInfo set) { Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; AutoSizeAxes = Axes.Y; @@ -20,36 +40,40 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new Drawable[] { + new AsyncLoadWrapper(new PreviewButton(set) + { + RelativeSizeAxes = Axes.X, + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, new DetailBox { - Child = new Container + Child = basic = new BasicStats(set) { RelativeSizeAxes = Axes.X, - Height = 42, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Vertical = 10 }, + Padding = new MarginPadding { Horizontal = 15 }, }, }, new DetailBox { - Child = new Container + Child = advanced = new AdvancedStats { RelativeSizeAxes = Axes.X, - Height = 35, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Vertical = 7.5f }, }, }, new DetailBox { - Child = new Container + Child = ratings = new UserRatings { RelativeSizeAxes = Axes.X, - Height = 110, - }, - }, - new DetailBox - { - Child = new Container - { - RelativeSizeAxes = Axes.X, - Height = 115, + Height = 95, + Margin = new MarginPadding { Top = 10 }, }, }, }; diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index cea497af8c..8200a9a373 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -22,6 +22,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private readonly Box tabsBg; + public readonly BeatmapPicker Picker; + public Header(BeatmapSetInfo set) { RelativeSizeAxes = Axes.X; @@ -35,6 +37,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Offset = new Vector2(0f, 1f), }; + FillFlowContainer buttons; + Details details; Children = new Drawable[] { new Container @@ -101,7 +105,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { RelativeSizeAxes = Axes.X, Height = 113, - Child = new BeatmapPicker(set), + Child = Picker = new BeatmapPicker(set), }, new OsuSpriteText { @@ -122,7 +126,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Top = 20 }, Child = new AuthorInfo(set.OnlineInfo), }, - new FillFlowContainer + buttons = new FillFlowContainer { RelativeSizeAxes = Axes.X, Height = 45, @@ -131,14 +135,12 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new HeaderButton[] { new FavouriteButton(), - new DownloadButton("Download", ""), - new DownloadButton("osu!direct", ""), }, }, }, }, }, - new Details + details = new Details(set) { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, @@ -147,6 +149,25 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }, }; + + Picker.Beatmap.ValueChanged += b => + { + details.Beatmap = b; + + buttons.Child = new FavouriteButton(); + if (b.OnlineInfo.HasVideo) + { + buttons.AddRange(new[] + { + new DownloadButton("Download", "with Video"), + new DownloadButton("Download", "without Video"), + }); + } + else + { + buttons.Add(new DownloadButton("Download", @"")); + } + }; } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs index b4c505b136..e311b6e886 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs @@ -22,9 +22,16 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private readonly BeatmapSetInfo set; private readonly Box successRateBackground; + private readonly SuccessRate successRate; private readonly FillFlowContainer metadataFlow; private readonly ScrollContainer descriptionScroll; + public BeatmapInfo Beatmap + { + get { return successRate.Beatmap; } + set { successRate.Beatmap = value; } + } + public Info(BeatmapSetInfo set) { this.set = set; @@ -85,12 +92,17 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, - Children = new[] + Children = new Drawable[] { successRateBackground = new Box { RelativeSizeAxes = Axes.Both, }, + successRate = new SuccessRate + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 20, Horizontal = 15 }, + }, }, }, }, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs new file mode 100644 index 0000000000..a86623048a --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -0,0 +1,137 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Extensions.Color4Extensions; +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.Containers; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class PreviewButton : OsuClickableContainer + { + private readonly BeatmapSetInfo set; + private readonly Box bg, progress; + private readonly SpriteIcon icon; + + private AudioManager audio; + private Track preview; + + private bool playing = false; + public bool Playing + { + get { return playing; } + set + { + if (value == playing) return; + playing = value; + + if (Playing) + { + icon.Icon = FontAwesome.fa_stop; + progress.FadeIn(100); + + loadPreview(); + preview.Start(); + } + else + { + icon.Icon = FontAwesome.fa_play; + progress.FadeOut(100); + preview.Stop(); + } + } + } + + public PreviewButton(BeatmapSetInfo set) + { + this.set = set; + Height = 42; + + Children = new Drawable[] + { + bg = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.25f), + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 3, + Child = progress = new Box + { + RelativeSizeAxes = Axes.Both, + Width = 0f, + Alpha = 0f, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_play, + Size = new Vector2(18), + Shadow = false, + }, + }; + + Action = () => Playing = !Playing; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, AudioManager audio) + { + this.audio = audio; + progress.Colour = colours.Yellow; + + loadPreview(); + } + + protected override void Update() + { + base.Update(); + + if (Playing) + { + progress.Width = (float)(preview.CurrentTime / preview.Length); + if (preview.HasCompleted) Playing = false; + } + } + + protected override bool OnHover(InputState state) + { + bg.FadeColour(Color4.Black.Opacity(0.5f), 100); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + bg.FadeColour(Color4.Black.Opacity(0.25f), 100); + } + + private void loadPreview() + { + if (preview?.HasCompleted ?? true) + { + preview = audio.Track.Get(set.OnlineInfo.Preview); + preview.Volume.Value = 0.5; + } + else + { + preview.Seek(0); + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs new file mode 100644 index 0000000000..88aef753ff --- /dev/null +++ b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs @@ -0,0 +1,117 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Beatmaps; +using osu.Game.Screens.Select.Details; +using System; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class SuccessRate : Container + { + private readonly FillFlowContainer header; + private readonly OsuSpriteText successRateLabel, successPercent, graphLabel; + private readonly Bar successRate; + private readonly Container percentContainer; + private readonly FailRetryGraph graph; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + var rate = (float)beatmap.OnlineInfo.PassCount / beatmap.OnlineInfo.PlayCount; + successPercent.Text = $"{Math.Round(rate * 100)}%"; + successRate.Length = rate; + + graph.Metrics = Beatmap.Metrics; + } + } + + public SuccessRate() + { + Children = new Drawable[] + { + header = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + successRateLabel = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Success Rate", + TextSize = 13, + }, + successRate = new Bar + { + RelativeSizeAxes = Axes.X, + Height = 5, + Margin = new MarginPadding { Top = 5 }, + }, + percentContainer = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = successPercent = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopCentre, + TextSize = 13, + }, + }, + graphLabel = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Points of Failure", + TextSize = 13, + Margin = new MarginPadding { Vertical = 20 }, + }, + }, + }, + graph = new FailRetryGraph + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5; + successRate.AccentColour = colours.Green; + successRate.BackgroundColour = colours.GrayD; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + graph.Padding = new MarginPadding { Top = header.DrawHeight }; + } + + protected override void Update() + { + base.Update(); + + percentContainer.Width = successRate.Length; + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs index 4fae3cac35..6e3a2019d0 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.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.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; @@ -68,12 +69,16 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { + Header header; + Info info; scrollContent.Children = new Drawable[] { - new Header(set), - new Info(set), + header = new Header(set), + info = new Info(set), }; + header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; + Show(); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7db65a0b4c..42dd1ad032 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -545,6 +545,15 @@ + + + + + + + + + @@ -570,4 +579,4 @@ --> - + \ No newline at end of file From 4be8899fb29b70ed7edace67c731d699cc3ebd2f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 11 Sep 2017 02:55:32 -0300 Subject: [PATCH 07/96] Move Length to BeatmapOnlineInfo. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 6 +++++- osu.Game/Beatmaps/BeatmapOnlineInfo.cs | 5 +++++ osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 5 ----- osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs | 8 +++----- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index 2d26c6c518..5bec99e5a5 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -46,7 +46,6 @@ namespace osu.Desktop.VisualTests.Tests FavouriteCount = 356, Submitted = new DateTime(2016, 2, 10), Ranked = new DateTime(2016, 6, 19), - Length = 118000, BPM = 236, Author = new User { @@ -75,6 +74,7 @@ namespace osu.Desktop.VisualTests.Tests }, OnlineInfo = new BeatmapOnlineInfo { + Length = 115000, HasVideo = false, CircleCount = 265, SliderCount = 71, @@ -103,6 +103,7 @@ namespace osu.Desktop.VisualTests.Tests }, OnlineInfo = new BeatmapOnlineInfo { + Length = 118000, HasVideo = false, CircleCount = 592, SliderCount = 62, @@ -131,6 +132,7 @@ namespace osu.Desktop.VisualTests.Tests }, OnlineInfo = new BeatmapOnlineInfo { + Length = 118000, HasVideo = false, CircleCount = 1042, SliderCount = 79, @@ -159,6 +161,7 @@ namespace osu.Desktop.VisualTests.Tests }, OnlineInfo = new BeatmapOnlineInfo { + Length = 118000, HasVideo = false, CircleCount = 1352, SliderCount = 69, @@ -187,6 +190,7 @@ namespace osu.Desktop.VisualTests.Tests }, OnlineInfo = new BeatmapOnlineInfo { + Length = 118000, HasVideo = false, CircleCount = 1730, SliderCount = 115, diff --git a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs index c9794107ce..399cabda99 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineInfo.cs @@ -10,6 +10,11 @@ namespace osu.Game.Beatmaps /// public class BeatmapOnlineInfo { + /// + /// The length in milliseconds of this beatmap's song. + /// + public double Length { get; set; } + /// /// Whether or not this beatmap has a background video. /// diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 8009ea5b9e..b53aee9661 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -44,11 +44,6 @@ namespace osu.Game.Beatmaps [JsonProperty(@"previewUrl")] public string Preview { get; set; } - /// - /// The length in milliseconds of this beatmap's song. - /// - public double Length { get; set; } - /// /// The beats per minute of this beatmap set's song. /// diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs index fa45a04b40..d5acfd2e43 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs @@ -25,6 +25,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { if (value == beatmap) return; beatmap = value; + + length.Value = TimeSpan.FromMilliseconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss"); circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); } @@ -40,11 +42,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Direction = FillDirection.Horizontal, Children = new[] { - length = new Statistic(FontAwesome.fa_clock_o, "Length") - { - Width = statWidth, - Value = TimeSpan.FromMilliseconds(set.OnlineInfo.Length).ToString(@"m\:ss"), - }, + length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth, From 169bfe134bfe9e8e047c8104e1dd8c3271de108a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 20:24:24 -0300 Subject: [PATCH 08/96] Fix incorrect BasicStats padding. --- osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs index 300eb3a8e1..9aed59272d 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -55,7 +55,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Vertical = 10 }, - Padding = new MarginPadding { Horizontal = 15 }, }, }, new DetailBox From a291bd30204b83f155f40c156c90f8217673f724 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 20:55:17 -0300 Subject: [PATCH 09/96] Add second beatmap set to test, fix some visual issues. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 201 ++++++++++++++++-- .../Overlays/OnlineBeatmapSet/AuthorInfo.cs | 1 - .../OnlineBeatmapSet/BeatmapPicker.cs | 4 +- osu.Game/Overlays/OnlineBeatmapSet/Info.cs | 15 +- .../OnlineBeatmapSet/PreviewButton.cs | 6 + .../Overlays/OnlineBeatmapSet/SuccessRate.cs | 1 + osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 1 - 7 files changed, 206 insertions(+), 23 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index 5bec99e5a5..be7127eaaf 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -1,4 +1,7 @@ -using System; +// 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.Framework.Allocation; @@ -24,18 +27,17 @@ namespace osu.Desktop.VisualTests.Tests [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - var r = rulesets.GetRuleset(3); + var mania = rulesets.GetRuleset(3); + var taiko = rulesets.GetRuleset(1); - AddStep(@"show lachryma", () => + AddStep(@"show first", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo { - OnlineBeatmapSetID = 415886, Metadata = new BeatmapMetadata { Title = @"Lachryma ", Artist = @"Kaneko Chiharu", - Author = @"Fresh Chicken", Source = @"SOUND VOLTEX III GRAVITY WARS", Tags = @"sdvx grace the 5th kac original song contest konami bemani", }, @@ -61,10 +63,9 @@ namespace osu.Desktop.VisualTests.Tests { new BeatmapInfo { - OnlineBeatmapID = 901048, StarDifficulty = 1.36, Version = @"BASIC", - Ruleset = r, + Ruleset = mania, Difficulty = new BeatmapDifficulty { CircleSize = 4, @@ -90,10 +91,9 @@ namespace osu.Desktop.VisualTests.Tests }, new BeatmapInfo { - OnlineBeatmapID = 901051, StarDifficulty = 2.22, Version = @"NOVICE", - Ruleset = r, + Ruleset = mania, Difficulty = new BeatmapDifficulty { CircleSize = 4, @@ -119,10 +119,9 @@ namespace osu.Desktop.VisualTests.Tests }, new BeatmapInfo { - OnlineBeatmapID = 901047, StarDifficulty = 3.49, Version = @"ADVANCED", - Ruleset = r, + Ruleset = mania, Difficulty = new BeatmapDifficulty { CircleSize = 4, @@ -148,10 +147,9 @@ namespace osu.Desktop.VisualTests.Tests }, new BeatmapInfo { - OnlineBeatmapID = 901049, StarDifficulty = 4.24, Version = @"EXHAUST", - Ruleset = r, + Ruleset = mania, Difficulty = new BeatmapDifficulty { CircleSize = 4, @@ -177,10 +175,9 @@ namespace osu.Desktop.VisualTests.Tests }, new BeatmapInfo { - OnlineBeatmapID = 901050, StarDifficulty = 5.26, Version = @"GRAVITY", - Ruleset = r, + Ruleset = mania, Difficulty = new BeatmapDifficulty { CircleSize = 4, @@ -207,6 +204,180 @@ namespace osu.Desktop.VisualTests.Tests }, }); }); + + AddStep(@"show second", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = @"Soumatou Labyrinth", + Artist = @"Yunomi with Momobako&miko", + Tags = @"mmbk.com yuzu__rinrin charlotte", + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Preview = @"https://b.ppy.sh/preview/625493.mp3", + PlayCount = 22996, + FavouriteCount = 58, + Submitted = new DateTime(2016, 6, 11), + Ranked = new DateTime(2016, 7, 12), + BPM = 160, + Author = new User + { + Username = @"komasy", + Id = 1980256, + }, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.40, + Version = @"yzrin's Kantan", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 7, + OverallDifficulty = 3, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 262, + SliderCount = 0, + PlayCount = 3952, + PassCount = 1373, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.23, + Version = @"Futsuu", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 6, + OverallDifficulty = 4, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 464, + SliderCount = 0, + PlayCount = 4833, + PassCount = 920, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 3.19, + Version = @"Muzukashii", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 6, + OverallDifficulty = 5, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 712, + SliderCount = 0, + PlayCount = 4405, + PassCount = 854, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 3.97, + Version = @"Charlotte's Oni", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 6, + OverallDifficulty = 5.5f, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 943, + SliderCount = 0, + PlayCount = 3950, + PassCount = 693, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 5.08, + Version = @"Labyrinth Oni", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 5, + OverallDifficulty = 6, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 1068, + SliderCount = 0, + PlayCount = 5856, + PassCount = 1207, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + }, + }); + }); } } } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs index af4566a3f8..a3df59d866 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 3a1fe9bd07..2bdffc687a 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -88,8 +88,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Top = 5 }, Children = new[] { - new Statistic(FontAwesome.fa_play_circle, 682712), - new Statistic(FontAwesome.fa_heart, 357), + new Statistic(FontAwesome.fa_play_circle, set.OnlineInfo.PlayCount), + new Statistic(FontAwesome.fa_heart, set.OnlineInfo.FavouriteCount), }, }, }, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs index e311b6e886..b820345839 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs @@ -151,11 +151,18 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }; - content.AddText(body, t => + if (!string.IsNullOrEmpty(body)) { - t.TextSize = 14; - t.Colour = textColour; - }); + content.AddText(body, t => + { + t.TextSize = 14; + t.Colour = textColour; + }); + } + else + { + Hide(); + } } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index a86623048a..fa64348902 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -110,6 +110,12 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } + protected override void Dispose(bool isDisposing) + { + Playing = false; + base.Dispose(isDisposing); + } + protected override bool OnHover(InputState state) { bg.FadeColour(Color4.Black.Opacity(0.5f), 100); diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs index 88aef753ff..c9326faf7f 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs @@ -70,6 +70,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { Anchor = Anchor.TopRight, Origin = Anchor.TopCentre, + Text = @"0%", TextSize = 13, }, }, diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs index 6e3a2019d0..0e215f059f 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; From d09bcabc8f90f36ae16c7bec076ea28011f6df1f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 21:00:20 -0300 Subject: [PATCH 10/96] Add a background to the overlay. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 3 +++ osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 23 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index be7127eaaf..832d5a1cb3 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -378,6 +378,9 @@ namespace osu.Desktop.VisualTests.Tests }, }); }); + + AddStep(@"hide", overlay.Hide); + AddStep(@"show without reload", overlay.Show); } } } diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs index 0e215f059f..ab6d308af9 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs @@ -6,6 +6,7 @@ using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -41,15 +42,23 @@ namespace osu.Game.Overlays Offset = new Vector2(0f, 1f), }; - Child = new ScrollContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - ScrollbarVisible = false, - Child = scrollContent = new ReverseChildIDFillFlowContainer + new Box { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + Child = scrollContent = new ReverseChildIDFillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, }, }; } From 680f2e232ca2e155dc118425322232cb4efe1046 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 21:24:43 -0300 Subject: [PATCH 11/96] Cleanup. --- .../Overlays/OnlineBeatmapSet/BasicStats.cs | 4 +- .../OnlineBeatmapSet/BeatmapPicker.cs | 7 +- .../OnlineBeatmapSet/FavouriteButton.cs | 13 +- .../Overlays/OnlineBeatmapSet/HeaderButton.cs | 48 +-- .../OnlineBeatmapSet/PreviewButton.cs | 287 +++++++++--------- .../Overlays/OnlineBeatmapSet/SuccessRate.cs | 6 - 6 files changed, 185 insertions(+), 180 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs index d5acfd2e43..05d13ebcda 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class BasicStats : Container { - private readonly Statistic length, bpm, circleCount, sliderCount; + private readonly Statistic length, circleCount, sliderCount; private BeatmapInfo beatmap; public BeatmapInfo Beatmap @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new[] { length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, - bpm = new Statistic(FontAwesome.fa_circle, "BPM") + new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth, Value = set.OnlineInfo.BPM.ToString(@"0.##"), diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 2bdffc687a..9f2dae5979 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -152,7 +152,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet public BeatmapTile(BeatmapInfo beatmap, Bindable bindable) { this.beatmap = beatmap; - this.bindable.BindTo(bindable); Size = new Vector2(size); Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; @@ -179,7 +178,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }; Action = () => this.bindable.Value = beatmap; - this.bindable.ValueChanged += bindable_ValueChanged; + this.bindable.ValueChanged += beatmapChanged; + this.bindable.BindTo(bindable); } protected override bool OnHover(InputState state) @@ -193,9 +193,10 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { if (bindable.Value != beatmap) fadeOut(); + base.OnHoverLost(state); } - private void bindable_ValueChanged(BeatmapInfo value) + private void beatmapChanged(BeatmapInfo value) { if (value == beatmap) fadeIn(); diff --git a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs index 140e2cd120..cef77dc43c 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs @@ -55,9 +55,18 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Favourited.ValueChanged += value => { - pink.FadeTo(value ? 1 : 0, 200); - icon.Icon = value ? FontAwesome.fa_heart : FontAwesome.fa_heart_o; + if (value) + { + pink.FadeIn(200); + icon.Icon = FontAwesome.fa_heart; + } + else + { + pink.FadeOut(200); + icon.Icon = FontAwesome.fa_heart_o; + } }; + Action = () => Favourited.Value = !Favourited.Value; } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs index 4c46b9e56f..d4f611c194 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs @@ -14,32 +14,32 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { private readonly Container content; - protected override Container Content => content; + protected override Container Content => content; - public HeaderButton() + public HeaderButton() + { + CornerRadius = 3; + Masking = true; + + InternalChildren = new Drawable[] { - CornerRadius = 3; - Masking = true; - - InternalChildren = new Drawable[] + new Box { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"094c5f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"0f7c9b"), - ColourDark = OsuColour.FromHex(@"094c5f"), - TriangleScale = 1.5f, - }, - content = new Container - { - RelativeSizeAxes = Axes.Both, - }, - }; - } + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"094c5f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"0f7c9b"), + ColourDark = OsuColour.FromHex(@"094c5f"), + TriangleScale = 1.5f, + }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }; + } } } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index fa64348902..6fd131c720 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -1,143 +1,144 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; -using osu.Framework.Extensions.Color4Extensions; -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.Containers; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class PreviewButton : OsuClickableContainer - { - private readonly BeatmapSetInfo set; - private readonly Box bg, progress; - private readonly SpriteIcon icon; - - private AudioManager audio; - private Track preview; - - private bool playing = false; - public bool Playing - { - get { return playing; } - set - { - if (value == playing) return; - playing = value; - - if (Playing) - { - icon.Icon = FontAwesome.fa_stop; - progress.FadeIn(100); - - loadPreview(); - preview.Start(); - } - else - { - icon.Icon = FontAwesome.fa_play; - progress.FadeOut(100); - preview.Stop(); - } - } - } - - public PreviewButton(BeatmapSetInfo set) - { - this.set = set; - Height = 42; - - Children = new Drawable[] - { - bg = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.25f), - }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 3, - Child = progress = new Box - { - RelativeSizeAxes = Axes.Both, - Width = 0f, - Alpha = 0f, - }, - }, - icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_play, - Size = new Vector2(18), - Shadow = false, - }, - }; - - Action = () => Playing = !Playing; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) - { - this.audio = audio; - progress.Colour = colours.Yellow; - - loadPreview(); - } - - protected override void Update() - { - base.Update(); - - if (Playing) - { - progress.Width = (float)(preview.CurrentTime / preview.Length); - if (preview.HasCompleted) Playing = false; - } - } - - protected override void Dispose(bool isDisposing) - { - Playing = false; - base.Dispose(isDisposing); - } - - protected override bool OnHover(InputState state) - { - bg.FadeColour(Color4.Black.Opacity(0.5f), 100); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - bg.FadeColour(Color4.Black.Opacity(0.25f), 100); - } - - private void loadPreview() - { - if (preview?.HasCompleted ?? true) - { - preview = audio.Track.Get(set.OnlineInfo.Preview); - preview.Volume.Value = 0.5; - } - else - { - preview.Seek(0); - } - } - } -} +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Extensions.Color4Extensions; +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.Containers; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class PreviewButton : OsuClickableContainer + { + private readonly BeatmapSetInfo set; + private readonly Box bg, progress; + private readonly SpriteIcon icon; + + private AudioManager audio; + private Track preview; + + private bool playing; + public bool Playing + { + get { return playing; } + set + { + if (value == playing) return; + playing = value; + + if (Playing) + { + icon.Icon = FontAwesome.fa_stop; + progress.FadeIn(100); + + loadPreview(); + preview.Start(); + } + else + { + icon.Icon = FontAwesome.fa_play; + progress.FadeOut(100); + preview.Stop(); + } + } + } + + public PreviewButton(BeatmapSetInfo set) + { + this.set = set; + Height = 42; + + Children = new Drawable[] + { + bg = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.25f), + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 3, + Child = progress = new Box + { + RelativeSizeAxes = Axes.Both, + Width = 0f, + Alpha = 0f, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_play, + Size = new Vector2(18), + Shadow = false, + }, + }; + + Action = () => Playing = !Playing; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, AudioManager audio) + { + this.audio = audio; + progress.Colour = colours.Yellow; + + loadPreview(); + } + + protected override void Update() + { + base.Update(); + + if (Playing) + { + progress.Width = (float)(preview.CurrentTime / preview.Length); + if (preview.HasCompleted) Playing = false; + } + } + + protected override void Dispose(bool isDisposing) + { + Playing = false; + base.Dispose(isDisposing); + } + + protected override bool OnHover(InputState state) + { + bg.FadeColour(Color4.Black.Opacity(0.5f), 100); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + bg.FadeColour(Color4.Black.Opacity(0.25f), 100); + base.OnHoverLost(state); + } + + private void loadPreview() + { + if (preview?.HasCompleted ?? true) + { + preview = audio.Track.Get(set.OnlineInfo.Preview); + preview.Volume.Value = 0.5; + } + else + { + preview.Seek(0); + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs index c9326faf7f..330ebedaca 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs @@ -106,12 +106,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet base.UpdateAfterChildren(); graph.Padding = new MarginPadding { Top = header.DrawHeight }; - } - - protected override void Update() - { - base.Update(); - percentContainer.Width = successRate.Length; } } From 97e5a0d4a311f69a10a47a464d9106f8bf352ea3 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 23:41:10 -0300 Subject: [PATCH 12/96] CI fixes. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 771 +++++++++--------- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 4 +- .../Overlays/OnlineBeatmapSet/AuthorInfo.cs | 173 ++-- .../Overlays/OnlineBeatmapSet/BasicStats.cs | 13 +- .../OnlineBeatmapSet/BeatmapPicker.cs | 528 ++++++------ osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 216 ++--- .../OnlineBeatmapSet/DownloadButton.cs | 118 +-- .../OnlineBeatmapSet/FavouriteButton.cs | 160 ++-- .../Overlays/OnlineBeatmapSet/HeaderButton.cs | 90 +- 9 files changed, 1040 insertions(+), 1033 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index 832d5a1cb3..b3421591f1 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -1,386 +1,385 @@ -// 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.Framework.Allocation; -using osu.Framework.Testing; -using osu.Game.Beatmaps; -using osu.Game.Overlays; -using osu.Game.Rulesets; -using osu.Game.Users; - -namespace osu.Desktop.VisualTests.Tests -{ - internal class TestCaseOnlineBeatmapSetOverlay : TestCase - { - public override string Description => @"view online beatmap sets"; - - private readonly OnlineBeatmapSetOverlay overlay; - - public TestCaseOnlineBeatmapSetOverlay() - { - Add(overlay = new OnlineBeatmapSetOverlay()); - } - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - var mania = rulesets.GetRuleset(3); - var taiko = rulesets.GetRuleset(1); - - AddStep(@"show first", () => - { - overlay.ShowBeatmapSet(new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = @"Lachryma ", - Artist = @"Kaneko Chiharu", - Source = @"SOUND VOLTEX III GRAVITY WARS", - Tags = @"sdvx grace the 5th kac original song contest konami bemani", - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Preview = @"https://b.ppy.sh/preview/415886.mp3", - PlayCount = 681380, - FavouriteCount = 356, - Submitted = new DateTime(2016, 2, 10), - Ranked = new DateTime(2016, 6, 19), - BPM = 236, - Author = new User - { - Username = @"Fresh Chicken", - Id = 3984370, - }, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778", - }, - }, - Beatmaps = new List - { - new BeatmapInfo - { - StarDifficulty = 1.36, - Version = @"BASIC", - Ruleset = mania, - Difficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 6.5f, - OverallDifficulty = 6.5f, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 115000, - HasVideo = false, - CircleCount = 265, - SliderCount = 71, - PlayCount = 47906, - PassCount = 19899, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.22, - Version = @"NOVICE", - Ruleset = mania, - Difficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7, - OverallDifficulty = 7, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - HasVideo = false, - CircleCount = 592, - SliderCount = 62, - PlayCount = 162021, - PassCount = 72116, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.49, - Version = @"ADVANCED", - Ruleset = mania, - Difficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7.5f, - OverallDifficulty = 7.5f, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - HasVideo = false, - CircleCount = 1042, - SliderCount = 79, - PlayCount = 225178, - PassCount = 73001, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 4.24, - Version = @"EXHAUST", - Ruleset = mania, - Difficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 8, - OverallDifficulty = 8, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - HasVideo = false, - CircleCount = 1352, - SliderCount = 69, - PlayCount = 131545, - PassCount = 42703, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 5.26, - Version = @"GRAVITY", - Ruleset = mania, - Difficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 8.5f, - OverallDifficulty = 8.5f, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - HasVideo = false, - CircleCount = 1730, - SliderCount = 115, - PlayCount = 117673, - PassCount = 24241, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - }, - }); - }); - - AddStep(@"show second", () => - { - overlay.ShowBeatmapSet(new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = @"Soumatou Labyrinth", - Artist = @"Yunomi with Momobako&miko", - Tags = @"mmbk.com yuzu__rinrin charlotte", - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Preview = @"https://b.ppy.sh/preview/625493.mp3", - PlayCount = 22996, - FavouriteCount = 58, - Submitted = new DateTime(2016, 6, 11), - Ranked = new DateTime(2016, 7, 12), - BPM = 160, - Author = new User - { - Username = @"komasy", - Id = 1980256, - }, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472", - }, - }, - Beatmaps = new List - { - new BeatmapInfo - { - StarDifficulty = 1.40, - Version = @"yzrin's Kantan", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty - { - CircleSize = 2, - DrainRate = 7, - OverallDifficulty = 3, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - HasVideo = false, - CircleCount = 262, - SliderCount = 0, - PlayCount = 3952, - PassCount = 1373, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.23, - Version = @"Futsuu", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty - { - CircleSize = 2, - DrainRate = 6, - OverallDifficulty = 4, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - HasVideo = false, - CircleCount = 464, - SliderCount = 0, - PlayCount = 4833, - PassCount = 920, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.19, - Version = @"Muzukashii", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty - { - CircleSize = 2, - DrainRate = 6, - OverallDifficulty = 5, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - HasVideo = false, - CircleCount = 712, - SliderCount = 0, - PlayCount = 4405, - PassCount = 854, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.97, - Version = @"Charlotte's Oni", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty - { - CircleSize = 5, - DrainRate = 6, - OverallDifficulty = 5.5f, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - HasVideo = false, - CircleCount = 943, - SliderCount = 0, - PlayCount = 3950, - PassCount = 693, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - new BeatmapInfo - { - StarDifficulty = 5.08, - Version = @"Labyrinth Oni", - Ruleset = taiko, - Difficulty = new BeatmapDifficulty - { - CircleSize = 5, - DrainRate = 5, - OverallDifficulty = 6, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - HasVideo = false, - CircleCount = 1068, - SliderCount = 0, - PlayCount = 5856, - PassCount = 1207, - }, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), - }, - }, - }, - }); - }); - - AddStep(@"hide", overlay.Hide); - AddStep(@"show without reload", overlay.Show); - } - } -} +// 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.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Rulesets; +using osu.Game.Users; + +namespace osu.Desktop.Tests.Visual +{ + internal class TestCaseOnlineBeatmapSetOverlay : OsuTestCase + { + public override string Description => @"view online beatmap sets"; + + private readonly OnlineBeatmapSetOverlay overlay; + + public TestCaseOnlineBeatmapSetOverlay() + { + Add(overlay = new OnlineBeatmapSetOverlay()); + } + + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + var mania = rulesets.GetRuleset(3); + var taiko = rulesets.GetRuleset(1); + + AddStep(@"show first", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = @"Lachryma ", + Artist = @"Kaneko Chiharu", + Source = @"SOUND VOLTEX III GRAVITY WARS", + Tags = @"sdvx grace the 5th kac original song contest konami bemani", + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Preview = @"https://b.ppy.sh/preview/415886.mp3", + PlayCount = 681380, + FavouriteCount = 356, + Submitted = new DateTime(2016, 2, 10), + Ranked = new DateTime(2016, 6, 19), + BPM = 236, + Author = new User + { + Username = @"Fresh Chicken", + Id = 3984370, + }, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.36, + Version = @"BASIC", + Ruleset = mania, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 6.5f, + OverallDifficulty = 6.5f, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 115000, + HasVideo = false, + CircleCount = 265, + SliderCount = 71, + PlayCount = 47906, + PassCount = 19899, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.22, + Version = @"NOVICE", + Ruleset = mania, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7, + OverallDifficulty = 7, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 118000, + HasVideo = false, + CircleCount = 592, + SliderCount = 62, + PlayCount = 162021, + PassCount = 72116, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 3.49, + Version = @"ADVANCED", + Ruleset = mania, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7.5f, + OverallDifficulty = 7.5f, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 118000, + HasVideo = false, + CircleCount = 1042, + SliderCount = 79, + PlayCount = 225178, + PassCount = 73001, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 4.24, + Version = @"EXHAUST", + Ruleset = mania, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 8, + OverallDifficulty = 8, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 118000, + HasVideo = false, + CircleCount = 1352, + SliderCount = 69, + PlayCount = 131545, + PassCount = 42703, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 5.26, + Version = @"GRAVITY", + Ruleset = mania, + Difficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 8.5f, + OverallDifficulty = 8.5f, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 118000, + HasVideo = false, + CircleCount = 1730, + SliderCount = 115, + PlayCount = 117673, + PassCount = 24241, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + }, + }); + }); + + AddStep(@"show second", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = @"Soumatou Labyrinth", + Artist = @"Yunomi with Momobako&miko", + Tags = @"mmbk.com yuzu__rinrin charlotte", + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Preview = @"https://b.ppy.sh/preview/625493.mp3", + PlayCount = 22996, + FavouriteCount = 58, + Submitted = new DateTime(2016, 6, 11), + Ranked = new DateTime(2016, 7, 12), + BPM = 160, + Author = new User + { + Username = @"komasy", + Id = 1980256, + }, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.40, + Version = @"yzrin's Kantan", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 7, + OverallDifficulty = 3, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 262, + SliderCount = 0, + PlayCount = 3952, + PassCount = 1373, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.23, + Version = @"Futsuu", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 6, + OverallDifficulty = 4, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 464, + SliderCount = 0, + PlayCount = 4833, + PassCount = 920, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 3.19, + Version = @"Muzukashii", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 2, + DrainRate = 6, + OverallDifficulty = 5, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 712, + SliderCount = 0, + PlayCount = 4405, + PassCount = 854, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 3.97, + Version = @"Charlotte's Oni", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 6, + OverallDifficulty = 5.5f, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 943, + SliderCount = 0, + PlayCount = 3950, + PassCount = 693, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 5.08, + Version = @"Labyrinth Oni", + Ruleset = taiko, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 5, + OverallDifficulty = 6, + ApproachRate = 10, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 193000, + HasVideo = false, + CircleCount = 1068, + SliderCount = 0, + PlayCount = 5856, + PassCount = 1207, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + }, + }); + }); + + AddStep(@"hide", overlay.Hide); + AddStep(@"show without reload", overlay.Show); + } + } +} diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index b53aee9661..6b59f0f298 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -25,12 +25,12 @@ namespace osu.Game.Beatmaps /// /// The date this beatmap set was ranked. /// - public DateTimeOffset Ranked { get; set; } + public DateTimeOffset? Ranked { get; set; } /// /// The date this beatmap set was last updated. /// - public DateTimeOffset LastUpdated { get; set; } + public DateTimeOffset? LastUpdated { get; set; } /// /// The different sizes of cover art for this beatmap set. diff --git a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs index a3df59d866..90d97f75c7 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs @@ -1,82 +1,91 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; -using osu.Game.Graphics.Sprites; -using osu.Game.Users; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class AuthorInfo : Container - { - private const float height = 50; - - public AuthorInfo(BeatmapSetOnlineInfo info) - { - RelativeSizeAxes = Axes.X; - Height = height; - - Children = new Drawable[] - { - new UpdateableAvatar - { - Size = new Vector2(height), - CornerRadius = 3, - Masking = true, - User = info.Author, - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.25f), - Type = EdgeEffectType.Shadow, - Radius = 3, - Offset = new Vector2(0f, 1f), - }, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Left = height + 5 }, - Children = new Drawable[] - { - new Field("made by", info.Author.Username, @"Exo2.0-RegularItalic"), - new Field("submitted on", info.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") - { - Margin = new MarginPadding { Top = 5 }, - }, - new Field(info.Ranked == null ? "last updated on " : "ranked on ", (info.Ranked == null ? info.Submitted : info.Ranked).ToString(@"MMM d, yyyy"), @"Exo2.0-Bold"), - }, - }, - }; - } - - private class Field : FillFlowContainer - { - public Field(string first, string second, string secondFont) - { - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - - Children = new[] - { - new OsuSpriteText - { - Text = $"{first} ", - TextSize = 13, - }, - new OsuSpriteText - { - Text = second, - TextSize = 13, - Font = secondFont, - }, - }; - } - } - } -} +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class AuthorInfo : Container + { + private const float height = 50; + + public AuthorInfo(BeatmapSetOnlineInfo info) + { + RelativeSizeAxes = Axes.X; + Height = height; + + FillFlowContainer fields; + Children = new Drawable[] + { + new UpdateableAvatar + { + Size = new Vector2(height), + CornerRadius = 3, + Masking = true, + User = info.Author, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }, + }, + fields = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Left = height + 5 }, + Children = new Drawable[] + { + new Field("made by", info.Author.Username, @"Exo2.0-RegularItalic"), + new Field("submitted on", info.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") + { + Margin = new MarginPadding { Top = 5 }, + }, + }, + }, + }; + + if (info.Ranked.HasValue) + { + fields.Add(new Field("ranked on ", info.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); + } + else if (info.LastUpdated.HasValue) + { + fields.Add(new Field("last updated on ", info.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); + } + } + + private class Field : FillFlowContainer + { + public Field(string first, string second, string secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new OsuSpriteText + { + Text = $"{first} ", + TextSize = 13, + }, + new OsuSpriteText + { + Text = second, + TextSize = 13, + Font = secondFont, + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs index 05d13ebcda..7772f34466 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs @@ -27,14 +27,13 @@ namespace osu.Game.Overlays.OnlineBeatmapSet beatmap = value; length.Value = TimeSpan.FromMilliseconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss"); - circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); - sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); + circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString("N0"); + sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString("N0"); } } public BasicStats(BeatmapSetInfo set) { - var statWidth = 0.25f; Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -42,14 +41,14 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Direction = FillDirection.Horizontal, Children = new[] { - length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, + length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = 0.25f }, new Statistic(FontAwesome.fa_circle, "BPM") { - Width = statWidth, + Width = 0.25f, Value = set.OnlineInfo.BPM.ToString(@"0.##"), }, - circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, - sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, + circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = 0.25f }, + sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = 0.25f }, }, }; } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 9f2dae5979..92b9644263 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -1,264 +1,264 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Linq; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Extensions.Color4Extensions; -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.Beatmaps.Drawables; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class BeatmapPicker : Container - { - private const float tile_icon_padding = 7; - private const float tile_spacing = 2; - - private readonly OsuSpriteText version, starRating; - - public readonly Bindable Beatmap = new Bindable(); - - public BeatmapPicker(BeatmapSetInfo set) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - TilesFillFlowContainer tileContainer; - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - tileContainer = new TilesFillFlowContainer - { - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, - OnLostHover = () => - { - showBeatmap(Beatmap.Value); - starRating.FadeOut(100); - }, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 10 }, - Spacing = new Vector2(5f), - Children = new[] - { - version = new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - TextSize = 20, - Font = @"Exo2.0-Bold", - }, - starRating = new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - TextSize = 13, - Font = @"Exo2.0-Bold", - Text = "Star Difficulty", - Alpha = 0, - Margin = new MarginPadding { Bottom = 1 }, - }, - }, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(10f), - Margin = new MarginPadding { Top = 5 }, - Children = new[] - { - new Statistic(FontAwesome.fa_play_circle, set.OnlineInfo.PlayCount), - new Statistic(FontAwesome.fa_heart, set.OnlineInfo.FavouriteCount), - }, - }, - }, - }, - }; - - Beatmap.Value = set.Beatmaps.First(); - Beatmap.ValueChanged += showBeatmap; - tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b, Beatmap) - { - OnHovered = beatmap => - { - showBeatmap(beatmap); - starRating.Text = string.Format("Star Difficulty {0:N2}", beatmap.StarDifficulty); - starRating.FadeIn(100); - }, - }); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - starRating.Colour = colours.Yellow; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - // done here so everything can bind in intialization and get the first trigger - Beatmap.TriggerChange(); - } - - private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; - - private class TilesFillFlowContainer : FillFlowContainer - { - public Action OnLostHover; - - protected override void OnHoverLost(InputState state) - { - base.OnHoverLost(state); - OnLostHover?.Invoke(); - } - } - - private class BeatmapTile : OsuClickableContainer - { - private const float transition_duration = 100; - private const float size = 52; - - private readonly BeatmapInfo beatmap; - private readonly Bindable bindable = new Bindable(); - - private readonly Container bg; - private readonly DifficultyIcon icon; - - public Action OnHovered; - - public BeatmapTile(BeatmapInfo beatmap, Bindable bindable) - { - this.beatmap = beatmap; - Size = new Vector2(size); - Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; - - Children = new Drawable[] - { - bg = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - }, - icon = new DifficultyIcon(beatmap) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(size - tile_icon_padding * 2), - Margin = new MarginPadding { Bottom = 1 }, - }, - }; - - Action = () => this.bindable.Value = beatmap; - this.bindable.ValueChanged += beatmapChanged; - this.bindable.BindTo(bindable); - } - - protected override bool OnHover(InputState state) - { - fadeIn(); - OnHovered?.Invoke(beatmap); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - if (bindable.Value != beatmap) - fadeOut(); - base.OnHoverLost(state); - } - - private void beatmapChanged(BeatmapInfo value) - { - if (value == beatmap) - fadeIn(); - else - fadeOut(); - } - - private void fadeIn() - { - bg.FadeIn(transition_duration); - icon.FadeIn(transition_duration); - } - - private void fadeOut() - { - bg.FadeOut(); - icon.FadeTo(0.7f, transition_duration); - } - } - - private class Statistic : FillFlowContainer - { - private readonly OsuSpriteText text; - - private int value; - public int Value - { - get { return value; } - set - { - this.value = value; - text.Text = Value.ToString(@"N0"); - } - } - - public Statistic(FontAwesome icon, int value = 0) - { - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Spacing = new Vector2(2f); - - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = icon, - Shadow = true, - Size = new Vector2(13), - }, - text = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = @"Exo2.0-SemiBoldItalic", - TextSize = 14, - }, - }; - - Value = value; - } - } - } -} +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; +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.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class BeatmapPicker : Container + { + private const float tile_icon_padding = 7; + private const float tile_spacing = 2; + + private readonly OsuSpriteText version, starRating; + + public readonly Bindable Beatmap = new Bindable(); + + public BeatmapPicker(BeatmapSetInfo set) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + TilesFillFlowContainer tileContainer; + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + tileContainer = new TilesFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, + OnLostHover = () => + { + showBeatmap(Beatmap.Value); + starRating.FadeOut(100); + }, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 10 }, + Spacing = new Vector2(5f), + Children = new[] + { + version = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + TextSize = 20, + Font = @"Exo2.0-Bold", + }, + starRating = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + TextSize = 13, + Font = @"Exo2.0-Bold", + Text = "Star Difficulty", + Alpha = 0, + Margin = new MarginPadding { Bottom = 1 }, + }, + }, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10f), + Margin = new MarginPadding { Top = 5 }, + Children = new[] + { + new Statistic(FontAwesome.fa_play_circle, set.OnlineInfo.PlayCount), + new Statistic(FontAwesome.fa_heart, set.OnlineInfo.FavouriteCount), + }, + }, + }, + }, + }; + + Beatmap.Value = set.Beatmaps.First(); + Beatmap.ValueChanged += showBeatmap; + tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b, Beatmap) + { + OnHovered = beatmap => + { + showBeatmap(beatmap); + starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##"); + starRating.FadeIn(100); + }, + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + starRating.Colour = colours.Yellow; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + // done here so everything can bind in intialization and get the first trigger + Beatmap.TriggerChange(); + } + + private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; + + private class TilesFillFlowContainer : FillFlowContainer + { + public Action OnLostHover; + + protected override void OnHoverLost(InputState state) + { + base.OnHoverLost(state); + OnLostHover?.Invoke(); + } + } + + private class BeatmapTile : OsuClickableContainer + { + private const float transition_duration = 100; + private const float size = 52; + + private readonly BeatmapInfo beatmap; + private readonly Bindable bindable = new Bindable(); + + private readonly Container bg; + private readonly DifficultyIcon icon; + + public Action OnHovered; + + public BeatmapTile(BeatmapInfo beatmap, Bindable bindable) + { + this.beatmap = beatmap; + Size = new Vector2(size); + Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; + + Children = new Drawable[] + { + bg = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + }, + icon = new DifficultyIcon(beatmap) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(size - tile_icon_padding * 2), + Margin = new MarginPadding { Bottom = 1 }, + }, + }; + + Action = () => this.bindable.Value = beatmap; + this.bindable.ValueChanged += beatmapChanged; + this.bindable.BindTo(bindable); + } + + protected override bool OnHover(InputState state) + { + fadeIn(); + OnHovered?.Invoke(beatmap); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if (bindable.Value != beatmap) + fadeOut(); + base.OnHoverLost(state); + } + + private void beatmapChanged(BeatmapInfo value) + { + if (value == beatmap) + fadeIn(); + else + fadeOut(); + } + + private void fadeIn() + { + bg.FadeIn(transition_duration); + icon.FadeIn(transition_duration); + } + + private void fadeOut() + { + bg.FadeOut(); + icon.FadeTo(0.7f, transition_duration); + } + } + + private class Statistic : FillFlowContainer + { + private readonly OsuSpriteText text; + + private int value; + public int Value + { + get { return value; } + set + { + this.value = value; + text.Text = Value.ToString(@"N0"); + } + } + + public Statistic(FontAwesome icon, int value = 0) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2f); + + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = icon, + Shadow = true, + Size = new Vector2(13), + }, + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = @"Exo2.0-SemiBoldItalic", + TextSize = 14, + }, + }; + + Value = value; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs index 9aed59272d..05ae8f64a8 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -1,108 +1,108 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; -using osu.Game.Screens.Select.Details; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class Details : FillFlowContainer - { - private readonly BasicStats basic; - private readonly AdvancedStats advanced; - private readonly UserRatings ratings; - - private BeatmapInfo beatmap; - public BeatmapInfo Beatmap - { - get { return beatmap; } - set - { - if (value == beatmap) return; - beatmap = value; - - basic.Beatmap = advanced.Beatmap = Beatmap; - ratings.Metrics = Beatmap.Metrics; - } - } - - public Details(BeatmapSetInfo set) - { - Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; - AutoSizeAxes = Axes.Y; - Spacing = new Vector2(1f); - - Children = new Drawable[] - { - new AsyncLoadWrapper(new PreviewButton(set) - { - RelativeSizeAxes = Axes.X, - }) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - new DetailBox - { - Child = basic = new BasicStats(set) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Vertical = 10 }, - }, - }, - new DetailBox - { - Child = advanced = new AdvancedStats - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Vertical = 7.5f }, - }, - }, - new DetailBox - { - Child = ratings = new UserRatings - { - RelativeSizeAxes = Axes.X, - Height = 95, - Margin = new MarginPadding { Top = 10 }, - }, - }, - }; - } - - private class DetailBox : Container - { - private Container content; - protected override Container Content => content; - - public DetailBox() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - content = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 15 }, - }, - }; - } - } - } -} +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Screens.Select.Details; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class Details : FillFlowContainer + { + private readonly BasicStats basic; + private readonly AdvancedStats advanced; + private readonly UserRatings ratings; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + basic.Beatmap = advanced.Beatmap = Beatmap; + ratings.Metrics = Beatmap.Metrics; + } + } + + public Details(BeatmapSetInfo set) + { + Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; + AutoSizeAxes = Axes.Y; + Spacing = new Vector2(1f); + + Children = new Drawable[] + { + new AsyncLoadWrapper(new PreviewButton(set) + { + RelativeSizeAxes = Axes.X, + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + new DetailBox + { + Child = basic = new BasicStats(set) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Vertical = 10 }, + }, + }, + new DetailBox + { + Child = advanced = new AdvancedStats + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Vertical = 7.5f }, + }, + }, + new DetailBox + { + Child = ratings = new UserRatings + { + RelativeSizeAxes = Axes.X, + Height = 95, + Margin = new MarginPadding { Top = 10 }, + }, + }, + }; + } + + private class DetailBox : Container + { + private readonly Container content; + protected override Container Content => content; + + public DetailBox() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 15 }, + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs index 96f811ca55..855aa3de93 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs @@ -1,59 +1,59 @@ -// 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.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class DownloadButton : HeaderButton - { - public DownloadButton(string title, string subtitle) - { - Width = 120; - RelativeSizeAxes = Axes.Y; - - Child = new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 10 }, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new[] - { - new OsuSpriteText - { - Text = title, - TextSize = 13, - Font = @"Exo2.0-Bold", - }, - new OsuSpriteText - { - Text = subtitle, - TextSize = 11, - Font = @"Exo2.0-Bold", - }, - }, - }, - new SpriteIcon - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Icon = FontAwesome.fa_download, - Size = new Vector2(16), - Margin = new MarginPadding { Right = 5 }, - }, - }, - }; - } - } -} +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class DownloadButton : HeaderButton + { + public DownloadButton(string title, string subtitle) + { + Width = 120; + RelativeSizeAxes = Axes.Y; + + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new[] + { + new OsuSpriteText + { + Text = title, + TextSize = 13, + Font = @"Exo2.0-Bold", + }, + new OsuSpriteText + { + Text = subtitle, + TextSize = 11, + Font = @"Exo2.0-Bold", + }, + }, + }, + new SpriteIcon + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Icon = FontAwesome.fa_download, + Size = new Vector2(16), + Margin = new MarginPadding { Right = 5 }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs index cef77dc43c..4998ea1c19 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs @@ -1,80 +1,80 @@ -// 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.Game.Graphics; -using osu.Game.Graphics.Backgrounds; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class FavouriteButton : HeaderButton - { - public readonly Bindable Favourited = new Bindable(); - - public FavouriteButton() - { - RelativeSizeAxes = Axes.Y; - - Container pink; - SpriteIcon icon; - Children = new Drawable[] - { - pink = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"9f015f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"cb2187"), - ColourDark = OsuColour.FromHex(@"9f015f"), - TriangleScale = 1.5f, - }, - }, - }, - icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_heart_o, - Size = new Vector2(18), - Shadow = false, - }, - }; - - Favourited.ValueChanged += value => - { - if (value) - { - pink.FadeIn(200); - icon.Icon = FontAwesome.fa_heart; - } - else - { - pink.FadeOut(200); - icon.Icon = FontAwesome.fa_heart_o; - } - }; - - Action = () => Favourited.Value = !Favourited.Value; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - Width = DrawHeight; - } - } -} +// 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.Game.Graphics; +using osu.Game.Graphics.Backgrounds; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class FavouriteButton : HeaderButton + { + public readonly Bindable Favourited = new Bindable(); + + public FavouriteButton() + { + RelativeSizeAxes = Axes.Y; + + Container pink; + SpriteIcon icon; + Children = new Drawable[] + { + pink = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"9f015f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"cb2187"), + ColourDark = OsuColour.FromHex(@"9f015f"), + TriangleScale = 1.5f, + }, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_heart_o, + Size = new Vector2(18), + Shadow = false, + }, + }; + + Favourited.ValueChanged += value => + { + if (value) + { + pink.FadeIn(200); + icon.Icon = FontAwesome.fa_heart; + } + else + { + pink.FadeOut(200); + icon.Icon = FontAwesome.fa_heart_o; + } + }; + + Action = () => Favourited.Value = !Favourited.Value; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Width = DrawHeight; + } + } +} diff --git a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs index d4f611c194..fe852ec83a 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs @@ -1,45 +1,45 @@ -// 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.Game.Graphics; -using osu.Game.Graphics.Backgrounds; -using osu.Game.Graphics.Containers; - -namespace osu.Game.Overlays.OnlineBeatmapSet -{ - public class HeaderButton : OsuClickableContainer - { - private readonly Container content; - - protected override Container Content => content; - - public HeaderButton() - { - CornerRadius = 3; - Masking = true; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"094c5f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"0f7c9b"), - ColourDark = OsuColour.FromHex(@"094c5f"), - TriangleScale = 1.5f, - }, - content = new Container - { - RelativeSizeAxes = Axes.Both, - }, - }; - } - } -} +// 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.Game.Graphics; +using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; + +namespace osu.Game.Overlays.OnlineBeatmapSet +{ + public class HeaderButton : OsuClickableContainer + { + private readonly Container content; + + protected override Container Content => content; + + public HeaderButton() + { + CornerRadius = 3; + Masking = true; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"094c5f"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"0f7c9b"), + ColourDark = OsuColour.FromHex(@"094c5f"), + TriangleScale = 1.5f, + }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} From d36fc134878d7e86c3bb50121f34a04958dc416d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 23:46:21 -0300 Subject: [PATCH 13/96] Make success rate percent move with the bar. --- osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs index 330ebedaca..4641bf8c32 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs @@ -33,6 +33,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet var rate = (float)beatmap.OnlineInfo.PassCount / beatmap.OnlineInfo.PlayCount; successPercent.Text = $"{Math.Round(rate * 100)}%"; successRate.Length = rate; + percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); graph.Metrics = Beatmap.Metrics; } @@ -106,7 +107,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet base.UpdateAfterChildren(); graph.Padding = new MarginPadding { Top = header.DrawHeight }; - percentContainer.Width = successRate.Length; } } } From 0e9dc6fb85ba9dcad7632ff07d77a4d5f57e28ba Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 12 Sep 2017 23:55:48 -0300 Subject: [PATCH 14/96] Don't recreate header buttons on beatmap change. --- .../Visual/TestCaseOnlineBeatmapSetOverlay.cs | 2 +- osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs index b3421591f1..5d17cd6b8f 100644 --- a/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs @@ -103,7 +103,7 @@ namespace osu.Desktop.Tests.Visual OnlineInfo = new BeatmapOnlineInfo { Length = 118000, - HasVideo = false, + HasVideo = true, CircleCount = 592, SliderCount = 62, PlayCount = 162021, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 8200a9a373..14cb4b653c 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -18,6 +18,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class Header : Container { + private const float transition_duration = 250; private const float tabs_height = 50; private readonly Box tabsBg; @@ -37,7 +38,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Offset = new Vector2(0f, 1f), }; - FillFlowContainer buttons; + DownloadButton noVideo, withVideo, withoutVideo; Details details; Children = new Drawable[] { @@ -126,15 +127,20 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Top = 20 }, Child = new AuthorInfo(set.OnlineInfo), }, - buttons = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.X, Height = 45, Spacing = new Vector2(5f), Margin = new MarginPadding { Top = 10 }, + LayoutDuration = transition_duration, + LayoutEasing = Easing.Out, Children = new HeaderButton[] { new FavouriteButton(), + noVideo = new DownloadButton("Download", @""), + withVideo = new DownloadButton("Download", "with Video"), + withoutVideo = new DownloadButton("Download", "without Video"), }, }, }, @@ -154,18 +160,17 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { details.Beatmap = b; - buttons.Child = new FavouriteButton(); if (b.OnlineInfo.HasVideo) { - buttons.AddRange(new[] - { - new DownloadButton("Download", "with Video"), - new DownloadButton("Download", "without Video"), - }); + noVideo.FadeOut(transition_duration); + withVideo.FadeIn(transition_duration); + withoutVideo.FadeIn(transition_duration); } else { - buttons.Add(new DownloadButton("Download", @"")); + noVideo.FadeIn(transition_duration); + withVideo.FadeOut(transition_duration); + withoutVideo.FadeOut(transition_duration); } }; } From 9e6f94b81842f8a70f1a1089a43b8d571bacddbd Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 00:13:45 -0300 Subject: [PATCH 15/96] Make BeatmapPicker buttons more independent. --- .../OnlineBeatmapSet/BeatmapPicker.cs | 81 +++++++++++++------ 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 92b9644263..303c874d94 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using OpenTK; using OpenTK.Graphics; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -25,6 +26,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private const float tile_icon_padding = 7; private const float tile_spacing = 2; + private readonly DifficultiesContainer difficulties; private readonly OsuSpriteText version, starRating; public readonly Bindable Beatmap = new Bindable(); @@ -34,7 +36,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - TilesFillFlowContainer tileContainer; Children = new Drawable[] { new FillFlowContainer @@ -44,7 +45,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Direction = FillDirection.Vertical, Children = new Drawable[] { - tileContainer = new TilesFillFlowContainer + difficulties = new DifficultiesContainer { AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, @@ -97,15 +98,26 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }; Beatmap.Value = set.Beatmaps.First(); - Beatmap.ValueChanged += showBeatmap; - tileContainer.ChildrenEnumerable = set.Beatmaps.Select(b => new BeatmapTile(b, Beatmap) + + Beatmap.ValueChanged += b => { + showBeatmap(b); + updateDifficultyButtons(); + }; + + difficulties.ChildrenEnumerable = set.Beatmaps.Select(b => new DifficultySelectorButton(b) + { + State = DifficultySelectorState.NotSelected, OnHovered = beatmap => { showBeatmap(beatmap); starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##"); starRating.FadeIn(100); }, + OnClicked = beatmap => + { + Beatmap.Value = beatmap; + }, }); } @@ -125,7 +137,12 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; - private class TilesFillFlowContainer : FillFlowContainer + private void updateDifficultyButtons() + { + difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected); + } + + private class DifficultiesContainer : FillFlowContainer { public Action OnLostHover; @@ -136,22 +153,40 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } - private class BeatmapTile : OsuClickableContainer + private class DifficultySelectorButton : OsuClickableContainer, IStateful { private const float transition_duration = 100; private const float size = 52; - private readonly BeatmapInfo beatmap; - private readonly Bindable bindable = new Bindable(); - private readonly Container bg; private readonly DifficultyIcon icon; - public Action OnHovered; + public readonly BeatmapInfo Beatmap; - public BeatmapTile(BeatmapInfo beatmap, Bindable bindable) + public Action OnHovered; + public Action OnClicked; + public event Action StateChanged; + + private DifficultySelectorState state; + public DifficultySelectorState State { - this.beatmap = beatmap; + get { return state; } + set + { + if (value == state) return; + state = value; + + StateChanged?.Invoke(State); + if (value == DifficultySelectorState.Selected) + fadeIn(); + else + fadeOut(); + } + } + + public DifficultySelectorButton(BeatmapInfo beatmap) + { + this.Beatmap = beatmap; Size = new Vector2(size); Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; @@ -176,32 +211,26 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Bottom = 1 }, }, }; - - Action = () => this.bindable.Value = beatmap; - this.bindable.ValueChanged += beatmapChanged; - this.bindable.BindTo(bindable); } protected override bool OnHover(InputState state) { fadeIn(); - OnHovered?.Invoke(beatmap); + OnHovered?.Invoke(Beatmap); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - if (bindable.Value != beatmap) + if (State == DifficultySelectorState.NotSelected) fadeOut(); base.OnHoverLost(state); } - private void beatmapChanged(BeatmapInfo value) + protected override bool OnClick(InputState state) { - if (value == beatmap) - fadeIn(); - else - fadeOut(); + OnClicked?.Invoke(Beatmap); + return base.OnClick(state); } private void fadeIn() @@ -260,5 +289,11 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Value = value; } } + + private enum DifficultySelectorState + { + Selected, + NotSelected, + } } } From 0a5c963c4b1790fc9be1a09c86569836ec080ae7 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 00:18:00 -0300 Subject: [PATCH 16/96] Remove redundant .this --- osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index 303c874d94..bea6f98382 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -186,7 +186,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet public DifficultySelectorButton(BeatmapInfo beatmap) { - this.Beatmap = beatmap; + Beatmap = beatmap; Size = new Vector2(size); Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; From 574d7b24ff82bf20ea86766d7f3c12187635cc53 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 12:07:31 -0300 Subject: [PATCH 17/96] Fix some visual issues. --- osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 52 +++++++++++++------ .../Overlays/OnlineBeatmapSet/SuccessRate.cs | 1 + 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 14cb4b653c..0525b32b36 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -20,6 +20,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { private const float transition_duration = 250; private const float tabs_height = 50; + private const float buttons_height = 45; + private const float buttons_spacing = 5; private readonly Box tabsBg; @@ -38,7 +40,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Offset = new Vector2(0f, 1f), }; - DownloadButton noVideo, withVideo, withoutVideo; + Container noVideoButtons; + FillFlowContainer videoButtons; Details details; Children = new Drawable[] { @@ -127,20 +130,39 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Top = 20 }, Child = new AuthorInfo(set.OnlineInfo), }, - new FillFlowContainer + new Container { RelativeSizeAxes = Axes.X, - Height = 45, - Spacing = new Vector2(5f), + Height = buttons_height, Margin = new MarginPadding { Top = 10 }, - LayoutDuration = transition_duration, - LayoutEasing = Easing.Out, - Children = new HeaderButton[] + Children = new Drawable[] { new FavouriteButton(), - noVideo = new DownloadButton("Download", @""), - withVideo = new DownloadButton("Download", "with Video"), - withoutVideo = new DownloadButton("Download", "without Video"), + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, + Children = new Drawable[] + { + noVideoButtons = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + Child = new DownloadButton("Download", @""), + }, + videoButtons = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Spacing = new Vector2(buttons_spacing), + Alpha = 0f, + Children = new[] + { + new DownloadButton("Download", "with Video"), + new DownloadButton("Download", "without Video"), + }, + }, + }, + }, }, }, }, @@ -162,15 +184,13 @@ namespace osu.Game.Overlays.OnlineBeatmapSet if (b.OnlineInfo.HasVideo) { - noVideo.FadeOut(transition_duration); - withVideo.FadeIn(transition_duration); - withoutVideo.FadeIn(transition_duration); + noVideoButtons.FadeOut(transition_duration); + videoButtons.FadeIn(transition_duration); } else { - noVideo.FadeIn(transition_duration); - withVideo.FadeOut(transition_duration); - withoutVideo.FadeOut(transition_duration); + noVideoButtons.FadeIn(transition_duration); + videoButtons.FadeOut(transition_duration); } }; } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs index 4641bf8c32..3389542e64 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs @@ -67,6 +67,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Width = 0f, Child = successPercent = new OsuSpriteText { Anchor = Anchor.TopRight, From 63c50f82eb3540253664969e08fe7275bc3272db Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 12:37:18 -0300 Subject: [PATCH 18/96] Make Info updateable. --- osu.Game/Overlays/OnlineBeatmapSet/Info.cs | 89 ++++++++++++-------- osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 24 +++--- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs index b820345839..7782e8b7ab 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Info.cs @@ -16,15 +16,27 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class Info : Container { + private const float transition_duration = 250; private const float metadata_width = 225; private const float spacing = 20; - private readonly BeatmapSetInfo set; - + private readonly MetadataSection description, source, tags; private readonly Box successRateBackground; private readonly SuccessRate successRate; - private readonly FillFlowContainer metadataFlow; - private readonly ScrollContainer descriptionScroll; + + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + source.Text = BeatmapSet.Metadata.Source; + tags.Text = BeatmapSet.Metadata.Tags; + } + } public BeatmapInfo Beatmap { @@ -32,10 +44,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet set { successRate.Beatmap = value; } } - public Info(BeatmapSetInfo set) + public Info() { - this.set = set; - RelativeSizeAxes = Axes.X; Height = 220; Masking = true; @@ -64,10 +74,11 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = metadata_width + OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing * 2 }, - Child = descriptionScroll = new ScrollContainer + Child = new ScrollContainer { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, + Child = description = new MetadataSection("Description"), }, }, new ScrollContainer @@ -79,11 +90,17 @@ namespace osu.Game.Overlays.OnlineBeatmapSet ScrollbarVisible = false, Padding = new MarginPadding { Horizontal = 10 }, Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing }, - Child = metadataFlow = new FillFlowContainer + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + LayoutDuration = transition_duration, + Children = new[] + { + source = new MetadataSection("Source"), + tags = new MetadataSection("Tags"), + }, }, }, new Container @@ -114,55 +131,59 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private void load(OsuColour colours) { successRateBackground.Colour = colours.GrayE; - descriptionScroll.Child = new MetadataSection("Description", "", colours.Gray5); - metadataFlow.Children = new[] - { - new MetadataSection("Source", set.Metadata.Source, colours.Gray5), - new MetadataSection("Tags", set.Metadata.Tags, colours.BlueDark), - }; + source.TextColour = description.TextColour = colours.Gray5; + tags.TextColour = colours.BlueDark; } private class MetadataSection : FillFlowContainer { private readonly OsuSpriteText header; + private readonly TextFlowContainer textFlow; - public MetadataSection(string title, string body, Color4 textColour) + public string Text + { + set + { + if (string.IsNullOrEmpty(value)) + { + this.FadeOut(transition_duration); + return; + } + + this.FadeIn(transition_duration); + textFlow.Clear(); + textFlow.AddText(value, s => s.TextSize = 14); + } + } + + public Color4 TextColour + { + get { return textFlow.Colour; } + set { textFlow.Colour = value; } + } + + public MetadataSection(string title) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; Spacing = new Vector2(5f); - TextFlowContainer content; - Children = new Drawable[] + InternalChildren = new Drawable[] { header = new OsuSpriteText { + Text = title, Font = @"Exo2.0-Bold", TextSize = 14, - Text = title, Shadow = false, Margin = new MarginPadding { Top = 20 }, }, - content = new TextFlowContainer + textFlow = new TextFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, }, }; - - if (!string.IsNullOrEmpty(body)) - { - content.AddText(body, t => - { - t.TextSize = 14; - t.Colour = textColour; - }); - } - else - { - Hide(); - } } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs index ab6d308af9..9dea34e06b 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.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.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; @@ -19,7 +20,8 @@ namespace osu.Game.Overlays public const float X_PADDING = 40; public const float RIGHT_WIDTH = 275; - private readonly ReverseChildIDFillFlowContainer scrollContent; + private readonly Header header; + private readonly Info info; public OnlineBeatmapSetOverlay() { @@ -53,14 +55,21 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, - Child = scrollContent = new ReverseChildIDFillFlowContainer + Child = new ReverseChildIDFillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + Children = new Drawable[] + { + // header = new Header(), + info = new Info(), + }, }, }, }; + + // header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; } protected override void PopIn() @@ -77,15 +86,8 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { - Header header; - Info info; - scrollContent.Children = new Drawable[] - { - header = new Header(set), - info = new Info(set), - }; - - header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; + /*header.BeatmapSet = */info.BeatmapSet = set; + info.Beatmap = set.Beatmaps.Last(); Show(); } From d83cd3ecf9eeadbf6e673c74294ff2ade10be342 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 18:25:23 -0300 Subject: [PATCH 19/96] Make Header and it's components updateable. --- .../Overlays/OnlineBeatmapSet/AuthorInfo.cs | 58 ++++++++++------ .../Overlays/OnlineBeatmapSet/BasicStats.cs | 23 +++++-- .../OnlineBeatmapSet/BeatmapPicker.cs | 59 +++++++++------- osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 24 +++++-- osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 68 +++++++++++++------ .../OnlineBeatmapSet/PreviewButton.cs | 27 ++++++-- osu.Game/Overlays/OnlineBeatmapSetOverlay.cs | 8 +-- 7 files changed, 176 insertions(+), 91 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs index 90d97f75c7..ce46e96380 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs @@ -16,20 +16,53 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { private const float height = 50; - public AuthorInfo(BeatmapSetOnlineInfo info) + private readonly UpdateableAvatar avatar; + private readonly FillFlowContainer fields; + + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + var i = BeatmapSet.OnlineInfo; + + avatar.User = i.Author; + fields.Children = new Drawable[] + { + new Field("made by", i.Author.Username, @"Exo2.0-RegularItalic"), + new Field("submitted on", i.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") + { + Margin = new MarginPadding { Top = 5 }, + }, + }; + + if (i.Ranked.HasValue) + { + fields.Add(new Field("ranked on ", i.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); + } + else if (i.LastUpdated.HasValue) + { + fields.Add(new Field("last updated on ", i.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); + } + } + } + + public AuthorInfo() { RelativeSizeAxes = Axes.X; Height = height; - FillFlowContainer fields; Children = new Drawable[] { - new UpdateableAvatar + avatar = new UpdateableAvatar { Size = new Vector2(height), CornerRadius = 3, Masking = true, - User = info.Author, EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.25f), @@ -43,25 +76,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Padding = new MarginPadding { Left = height + 5 }, - Children = new Drawable[] - { - new Field("made by", info.Author.Username, @"Exo2.0-RegularItalic"), - new Field("submitted on", info.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") - { - Margin = new MarginPadding { Top = 5 }, - }, - }, }, }; - - if (info.Ranked.HasValue) - { - fields.Add(new Field("ranked on ", info.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); - } - else if (info.LastUpdated.HasValue) - { - fields.Add(new Field("last updated on ", info.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); - } } private class Field : FillFlowContainer diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs index 7772f34466..947bc111e0 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs @@ -15,7 +15,20 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class BasicStats : Container { - private readonly Statistic length, circleCount, sliderCount; + private readonly Statistic length, bpm, circleCount, sliderCount; + + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + bpm.Value = BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); + } + } private BeatmapInfo beatmap; public BeatmapInfo Beatmap @@ -32,7 +45,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } - public BasicStats(BeatmapSetInfo set) + public BasicStats() { Child = new FillFlowContainer { @@ -42,11 +55,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new[] { length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = 0.25f }, - new Statistic(FontAwesome.fa_circle, "BPM") - { - Width = 0.25f, - Value = set.OnlineInfo.BPM.ToString(@"0.##"), - }, + bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = 0.25f }, circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = 0.25f }, sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = 0.25f }, }, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs index bea6f98382..d7b9fa49bd 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs @@ -28,10 +28,42 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private readonly DifficultiesContainer difficulties; private readonly OsuSpriteText version, starRating; + private readonly Statistic plays, favourites; public readonly Bindable Beatmap = new Bindable(); - public BeatmapPicker(BeatmapSetInfo set) + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + Beatmap.Value = BeatmapSet.Beatmaps.First(); + plays.Value = BeatmapSet.OnlineInfo.PlayCount; + favourites.Value = BeatmapSet.OnlineInfo.FavouriteCount; + difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Select(b => new DifficultySelectorButton(b) + { + State = DifficultySelectorState.NotSelected, + OnHovered = beatmap => + { + showBeatmap(beatmap); + starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##"); + starRating.FadeIn(100); + }, + OnClicked = beatmap => + { + Beatmap.Value = beatmap; + }, + }); + + updateDifficultyButtons(); + } + } + + public BeatmapPicker() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -89,36 +121,19 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Margin = new MarginPadding { Top = 5 }, Children = new[] { - new Statistic(FontAwesome.fa_play_circle, set.OnlineInfo.PlayCount), - new Statistic(FontAwesome.fa_heart, set.OnlineInfo.FavouriteCount), + plays = new Statistic(FontAwesome.fa_play_circle), + favourites = new Statistic(FontAwesome.fa_heart), }, }, }, }, }; - Beatmap.Value = set.Beatmaps.First(); - Beatmap.ValueChanged += b => { showBeatmap(b); updateDifficultyButtons(); }; - - difficulties.ChildrenEnumerable = set.Beatmaps.Select(b => new DifficultySelectorButton(b) - { - State = DifficultySelectorState.NotSelected, - OnHovered = beatmap => - { - showBeatmap(beatmap); - starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##"); - starRating.FadeIn(100); - }, - OnClicked = beatmap => - { - Beatmap.Value = beatmap; - }, - }); } [BackgroundDependencyLoader] @@ -261,7 +276,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } - public Statistic(FontAwesome icon, int value = 0) + public Statistic(FontAwesome icon) { AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; @@ -285,8 +300,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet TextSize = 14, }, }; - - Value = value; } } diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs index 05ae8f64a8..e507ba8e5c 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -14,10 +14,24 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class Details : FillFlowContainer { + private readonly PreviewButton preview; private readonly BasicStats basic; private readonly AdvancedStats advanced; private readonly UserRatings ratings; + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + basic.BeatmapSet = preview.BeatmapSet = BeatmapSet; + } + } + private BeatmapInfo beatmap; public BeatmapInfo Beatmap { @@ -32,7 +46,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } - public Details(BeatmapSetInfo set) + public Details() { Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; AutoSizeAxes = Axes.Y; @@ -40,17 +54,13 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new Drawable[] { - new AsyncLoadWrapper(new PreviewButton(set) + preview = new PreviewButton { RelativeSizeAxes = Axes.X, - }) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, }, new DetailBox { - Child = basic = new BasicStats(set) + Child = basic = new BasicStats() { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 0525b32b36..0561bac702 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -24,10 +24,50 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private const float buttons_spacing = 5; private readonly Box tabsBg; + private readonly Container coverContainer; + private readonly OsuSpriteText title, artist; + private readonly AuthorInfo author; + private readonly Details details; + + private DelayedLoadWrapper cover; public readonly BeatmapPicker Picker; - public Header(BeatmapSetInfo set) + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + Picker.BeatmapSet = author.BeatmapSet = details.BeatmapSet = BeatmapSet; + title.Text = BeatmapSet.Metadata.Title; + artist.Text = BeatmapSet.Metadata.Artist; + + if (cover != null) + cover.FadeOut(400, Easing.Out); + + coverContainer.Add(cover = new DelayedLoadWrapper(new BeatmapSetCover(BeatmapSet) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + OnLoadComplete = d => + { + d.FadeInFromZero(400, Easing.Out); + }, + }) + { + RelativeSizeAxes = Axes.Both, + TimeBeforeLoad = 300 + }); + } + } + + public Header() { RelativeSizeAxes = Axes.X; Height = 400; @@ -42,7 +82,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Container noVideoButtons; FillFlowContainer videoButtons; - Details details; Children = new Drawable[] { new Container @@ -73,20 +112,9 @@ namespace osu.Game.Overlays.OnlineBeatmapSet RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - new DelayedLoadWrapper(new BeatmapSetCover(set) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fill, - OnLoadComplete = d => - { - d.FadeInFromZero(400, Easing.Out); - }, - }) + coverContainer = new Container { RelativeSizeAxes = Axes.Both, - TimeBeforeLoad = 300 }, new Box { @@ -109,17 +137,15 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { RelativeSizeAxes = Axes.X, Height = 113, - Child = Picker = new BeatmapPicker(set), + Child = Picker = new BeatmapPicker(), }, - new OsuSpriteText + title = new OsuSpriteText { - Text = set.Metadata.Title, Font = @"Exo2.0-BoldItalic", TextSize = 37, }, - new OsuSpriteText + artist = new OsuSpriteText { - Text = set.Metadata.Artist, Font = @"Exo2.0-SemiBoldItalic", TextSize = 25, }, @@ -128,7 +154,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Top = 20 }, - Child = new AuthorInfo(set.OnlineInfo), + Child = author = new AuthorInfo(), }, new Container { @@ -168,7 +194,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, }, }, - details = new Details(set) + details = new Details { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index 6fd131c720..e3fa7ccb17 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -19,13 +19,27 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { public class PreviewButton : OsuClickableContainer { - private readonly BeatmapSetInfo set; private readonly Box bg, progress; private readonly SpriteIcon icon; private AudioManager audio; private Track preview; + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet + { + get { return beatmapSet; } + set + { + if (value == beatmapSet) return; + beatmapSet = value; + + Playing = false; + preview = null; + loadPreview(); + } + } + private bool playing; public bool Playing { @@ -35,6 +49,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet if (value == playing) return; playing = value; + if (progress == null) return; + if (Playing) { icon.Icon = FontAwesome.fa_stop; @@ -52,9 +68,8 @@ namespace osu.Game.Overlays.OnlineBeatmapSet } } - public PreviewButton(BeatmapSetInfo set) + public PreviewButton() { - this.set = set; Height = 42; Children = new Drawable[] @@ -95,8 +110,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { this.audio = audio; progress.Colour = colours.Yellow; - - loadPreview(); } protected override void Update() @@ -130,9 +143,9 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private void loadPreview() { - if (preview?.HasCompleted ?? true) + if (preview == null || (preview?.HasCompleted ?? true) && BeatmapSet != null) { - preview = audio.Track.Get(set.OnlineInfo.Preview); + preview = audio.Track.Get(BeatmapSet.OnlineInfo.Preview); preview.Volume.Value = 0.5; } else diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs index 9dea34e06b..8db211e352 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; @@ -62,14 +61,14 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - // header = new Header(), + header = new Header(), info = new Info(), }, }, }, }; - // header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; + header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b; } protected override void PopIn() @@ -86,8 +85,7 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { - /*header.BeatmapSet = */info.BeatmapSet = set; - info.Beatmap = set.Beatmaps.Last(); + header.BeatmapSet = info.BeatmapSet = set; Show(); } From 022e39b8431de8643d073719cccf5b94d6050c83 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 13 Sep 2017 18:31:53 -0300 Subject: [PATCH 20/96] CI fixes. --- osu.Game/Overlays/OnlineBeatmapSet/Details.cs | 2 +- osu.Game/Overlays/OnlineBeatmapSet/Header.cs | 4 +--- osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs index e507ba8e5c..958cc2cd18 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Details.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet }, new DetailBox { - Child = basic = new BasicStats() + Child = basic = new BasicStats { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs index 0561bac702..2cd07b2212 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/Header.cs @@ -46,9 +46,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet title.Text = BeatmapSet.Metadata.Title; artist.Text = BeatmapSet.Metadata.Artist; - if (cover != null) - cover.FadeOut(400, Easing.Out); - + cover?.FadeOut(400, Easing.Out); coverContainer.Add(cover = new DelayedLoadWrapper(new BeatmapSetCover(BeatmapSet) { Anchor = Anchor.Centre, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index e3fa7ccb17..1dddf4a4a3 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -143,7 +143,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet private void loadPreview() { - if (preview == null || (preview?.HasCompleted ?? true) && BeatmapSet != null) + if (preview == null || preview.HasCompleted && BeatmapSet != null) { preview = audio.Track.Get(BeatmapSet.OnlineInfo.Preview); preview.Volume.Value = 0.5; From e7c9ad245e71bbbef17e07ed83c21f48d143011b Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 15 Sep 2017 09:24:31 +0300 Subject: [PATCH 21/96] Fix icons in main button system jumps on one side for a long time --- osu.Game/Screens/Menu/Button.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 6952f66f95..ccd61643ce 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -121,13 +121,14 @@ namespace osu.Game.Screens.Menu }; } + private bool rightward; + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); if (!IsHovered) return; - bool rightward = beatIndex % 2 == 1; double duration = timingPoint.BeatLength / 2; icon.RotateTo(rightward ? 10 : -10, duration * 2, Easing.InOutSine); @@ -139,6 +140,8 @@ namespace osu.Game.Screens.Menu i => i.MoveToY(0, duration, Easing.In), i => i.ScaleTo(new Vector2(1, 0.9f), duration, Easing.In) ); + + rightward = !rightward; } protected override bool OnHover(InputState state) @@ -152,7 +155,7 @@ namespace osu.Game.Screens.Menu double duration = TimeUntilNextBeat; icon.ClearTransforms(); - icon.RotateTo(10, duration, Easing.InOutSine); + icon.RotateTo(rightward ? -10 : 10, duration, Easing.InOutSine); icon.ScaleTo(new Vector2(1, 0.9f), duration, Easing.Out); return true; } From ddaf28d7f641d02a94dc36f269e2873c9e971013 Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 14:28:53 +0200 Subject: [PATCH 22/96] Integrate storyboards with gameplay. --- osu.Game/Beatmaps/Beatmap.cs | 15 ++++++++ osu.Game/Beatmaps/BeatmapInfo.cs | 1 + osu.Game/Screens/Play/Player.cs | 34 ++++++++++++++++--- .../Drawables/DrawableStoryboard.cs | 10 ++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 458c2304f2..23fc7ca9ea 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -46,6 +46,21 @@ namespace osu.Game.Beatmaps /// public Storyboard Storyboard = new Storyboard(); + /// + /// Whether this beatmap's Storyboard uses the background texture in its Background layer. + /// + public bool StoryboardUsesBackground + { + get + { + var backgroundPath = BeatmapInfo.BeatmapSet.Metadata.BackgroundFile?.ToLowerInvariant(); + if (backgroundPath == null) + return false; + + return Storyboard.GetLayer("Background").Elements.Any(e => e.Path.ToLowerInvariant() == backgroundPath); + } + } + /// /// Constructs a new beatmap. /// diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 0776669811..2dc4b44ed7 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -75,6 +75,7 @@ namespace osu.Game.Beatmaps public bool LetterboxInBreaks { get; set; } public bool WidescreenStoryboard { get; set; } + public float StoryboardAspect => WidescreenStoryboard ? 16 / 9f : 4 / 3f; // Editor // This bookmarks stuff is necessary because DB doesn't know how to store int[] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 593abb7d26..d9e962a9b2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,8 @@ using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Storyboards.Drawables; +using OpenTK.Graphics; namespace osu.Game.Screens.Play { @@ -66,6 +68,9 @@ namespace osu.Game.Screens.Play #endregion + private DrawableStoryboard storyboard; + private bool storyboardUsesBackground; + private HUDOverlay hudOverlay; private FailOverlay failOverlay; @@ -145,6 +150,15 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { + new Container + { + RelativeSizeAxes = Axes.Both, + Clock = offsetClock, + Children = new Drawable[] + { + storyboard = beatmap.Storyboard.CreateDrawable(), + } + }, pauseContainer = new PauseContainer { AudioClock = decoupledClock, @@ -196,6 +210,10 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); + storyboardUsesBackground = beatmap.StoryboardUsesBackground; + storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; + storyboard.Masking = true; + hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindRulesetContainer(RulesetContainer); @@ -266,12 +284,11 @@ namespace osu.Game.Screens.Play return; (Background as BackgroundScreenBeatmap)?.BlurTo(Vector2.Zero, 1500, Easing.OutQuint); - Background?.FadeTo(1 - (float)dimLevel, 1500, Easing.OutQuint); + + applyDim(); + dimLevel.ValueChanged += newDim => applyDim(); Content.Alpha = 0; - - dimLevel.ValueChanged += newDim => Background?.FadeTo(1 - (float)newDim, 800); - Content .ScaleTo(0.7f) .ScaleTo(1, 750, Easing.OutQuint) @@ -310,6 +327,15 @@ namespace osu.Game.Screens.Play return true; } + private void applyDim() + { + var opacity = 1 - (float)dimLevel; + storyboard.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); + storyboard.FadeTo(opacity == 0 ? 0 : 1); + + Background?.FadeTo(storyboardUsesBackground ? 0 : opacity, 800, Easing.OutQuint); + } + private void fadeOut() { const float fade_out_duration = 250; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index f88e5d118f..73fb942eb2 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -14,6 +14,9 @@ namespace osu.Game.Storyboards.Drawables { public Storyboard Storyboard { get; private set; } + private readonly Container content; + protected override Container Content => content; + protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480); public override bool HandleInput => false; @@ -39,6 +42,13 @@ namespace osu.Game.Storyboards.Drawables Size = new Vector2(640, 480); Anchor = Anchor.Centre; Origin = Anchor.Centre; + + AddInternal(content = new Container + { + Size = new Vector2(640, 480), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); } [BackgroundDependencyLoader] From cb8029af9ee2fa9d21994c659a55a0bff760f481 Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 15:44:36 +0200 Subject: [PATCH 23/96] Add a setting to hide storyboards. --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ .../Sections/Graphics/DetailSettings.cs | 17 +++++++++++++++++ osu.Game/Screens/Play/Player.cs | 14 +++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 44a6af841c..713207170e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -54,6 +54,8 @@ namespace osu.Game.Configuration // Graphics Set(OsuSetting.ShowFpsDisplay, false); + Set(OsuSetting.ShowStoryboard, true); + Set(OsuSetting.MenuParallax, true); Set(OsuSetting.SnakingInSliders, true); @@ -87,6 +89,7 @@ namespace osu.Game.Configuration GameplayCursorSize, AutoCursorSize, DimLevel, + ShowStoryboard, KeyOverlay, FloatingComments, PlaybackSpeed, diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index c068da8129..66b5dbfe06 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -1,10 +1,27 @@ // 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.Graphics; +using osu.Game.Configuration; + namespace osu.Game.Overlays.Settings.Sections.Graphics { public class DetailSettings : SettingsSubsection { protected override string Header => "Detail Settings"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SettingsCheckbox + { + LabelText = "Storyboards", + Bindable = config.GetBindable(OsuSetting.ShowStoryboard) + }, + }; + } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d9e962a9b2..a7124dee63 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -61,6 +61,7 @@ namespace osu.Game.Screens.Play #region User Settings private Bindable dimLevel; + private Bindable showStoryboard; private Bindable mouseWheelDisabled; private Bindable userAudioOffset; @@ -82,6 +83,7 @@ namespace osu.Game.Screens.Play this.api = api; dimLevel = config.GetBindable(OsuSetting.DimLevel); + showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); @@ -213,6 +215,7 @@ namespace osu.Game.Screens.Play storyboardUsesBackground = beatmap.StoryboardUsesBackground; storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; storyboard.Masking = true; + storyboard.Alpha = showStoryboard ? 1 : 0; hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindRulesetContainer(RulesetContainer); @@ -285,8 +288,9 @@ namespace osu.Game.Screens.Play (Background as BackgroundScreenBeatmap)?.BlurTo(Vector2.Zero, 1500, Easing.OutQuint); - applyDim(); - dimLevel.ValueChanged += newDim => applyDim(); + dimLevel.ValueChanged += value => updateBackgroundElements(); + showStoryboard.ValueChanged += value => updateBackgroundElements(); + updateBackgroundElements(); Content.Alpha = 0; Content @@ -327,13 +331,13 @@ namespace osu.Game.Screens.Play return true; } - private void applyDim() + private void updateBackgroundElements() { var opacity = 1 - (float)dimLevel; storyboard.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboard.FadeTo(opacity == 0 ? 0 : 1); + storyboard.FadeTo(!showStoryboard || opacity == 0 ? 0 : 1, 800); - Background?.FadeTo(storyboardUsesBackground ? 0 : opacity, 800, Easing.OutQuint); + Background?.FadeTo(showStoryboard && storyboardUsesBackground ? 0 : opacity, 800, Easing.OutQuint); } private void fadeOut() From 7c3ce7e830c9783c89ac6c8fafb943a831e5b6fb Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 15:58:55 +0200 Subject: [PATCH 24/96] Unbind events affecting the background after gameplay has ended. --- osu.Game/Screens/Play/Player.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a7124dee63..d0f0280c74 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -288,8 +288,8 @@ namespace osu.Game.Screens.Play (Background as BackgroundScreenBeatmap)?.BlurTo(Vector2.Zero, 1500, Easing.OutQuint); - dimLevel.ValueChanged += value => updateBackgroundElements(); - showStoryboard.ValueChanged += value => updateBackgroundElements(); + dimLevel.ValueChanged += dimLevel_ValueChanged; + showStoryboard.ValueChanged += showStoryboard_ValueChanged; updateBackgroundElements(); Content.Alpha = 0; @@ -331,6 +331,12 @@ namespace osu.Game.Screens.Play return true; } + private void dimLevel_ValueChanged(double newValue) + => updateBackgroundElements(); + + private void showStoryboard_ValueChanged(bool newValue) + => updateBackgroundElements(); + private void updateBackgroundElements() { var opacity = 1 - (float)dimLevel; @@ -342,6 +348,9 @@ namespace osu.Game.Screens.Play private void fadeOut() { + dimLevel.ValueChanged -= dimLevel_ValueChanged; + showStoryboard.ValueChanged -= showStoryboard_ValueChanged; + const float fade_out_duration = 250; RulesetContainer?.FadeOut(fade_out_duration); From c8cdf6787e6d029eb91d801c63ad05540e21393f Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 16:26:18 +0200 Subject: [PATCH 25/96] Better property name. --- osu.Game/Beatmaps/Beatmap.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 23fc7ca9ea..44331d9679 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -47,9 +47,9 @@ namespace osu.Game.Beatmaps public Storyboard Storyboard = new Storyboard(); /// - /// Whether this beatmap's Storyboard uses the background texture in its Background layer. + /// Whether this beatmap's background should be hidden while its storyboard is being displayed. /// - public bool StoryboardUsesBackground + public bool StoryboardReplacesBackground { get { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d0f0280c74..7675ba0ee4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -70,7 +70,7 @@ namespace osu.Game.Screens.Play #endregion private DrawableStoryboard storyboard; - private bool storyboardUsesBackground; + private bool storyboardReplacesBackground; private HUDOverlay hudOverlay; private FailOverlay failOverlay; @@ -212,7 +212,7 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); - storyboardUsesBackground = beatmap.StoryboardUsesBackground; + storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; storyboard.Masking = true; storyboard.Alpha = showStoryboard ? 1 : 0; @@ -341,9 +341,9 @@ namespace osu.Game.Screens.Play { var opacity = 1 - (float)dimLevel; storyboard.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboard.FadeTo(!showStoryboard || opacity == 0 ? 0 : 1, 800); + storyboard.FadeTo(!showStoryboard || opacity == 0 ? 0 : 1, 200); - Background?.FadeTo(showStoryboard && storyboardUsesBackground ? 0 : opacity, 800, Easing.OutQuint); + Background?.FadeTo(showStoryboard && storyboardReplacesBackground ? 0 : opacity, 800, Easing.OutQuint); } private void fadeOut() From 4a1576213923c7e663b1d8007c3bd174e0df1d39 Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 16:50:10 +0200 Subject: [PATCH 26/96] Don't create drawables for hidden storyboards. --- osu.Game/Screens/Play/Player.cs | 34 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7675ba0ee4..8a82c14d2d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -69,6 +69,7 @@ namespace osu.Game.Screens.Play #endregion + private Container storyboardContainer; private DrawableStoryboard storyboard; private bool storyboardReplacesBackground; @@ -152,14 +153,10 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - new Container + storyboardContainer = new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, - Children = new Drawable[] - { - storyboard = beatmap.Storyboard.CreateDrawable(), - } }, pauseContainer = new PauseContainer { @@ -212,10 +209,8 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); - storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; - storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; - storyboard.Masking = true; - storyboard.Alpha = showStoryboard ? 1 : 0; + if (showStoryboard) + initializeStoryboard(); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindRulesetContainer(RulesetContainer); @@ -232,6 +227,17 @@ namespace osu.Game.Screens.Play scoreProcessor.Failed += onFail; } + private void initializeStoryboard() + { + var beatmap = Beatmap.Value.Beatmap; + + storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; + + storyboardContainer.Add(storyboard = beatmap.Storyboard.CreateDrawable()); + storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; + storyboard.Masking = true; + } + public void Restart() { sampleRestart?.Play(); @@ -340,10 +346,14 @@ namespace osu.Game.Screens.Play private void updateBackgroundElements() { var opacity = 1 - (float)dimLevel; - storyboard.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboard.FadeTo(!showStoryboard || opacity == 0 ? 0 : 1, 200); - Background?.FadeTo(showStoryboard && storyboardReplacesBackground ? 0 : opacity, 800, Easing.OutQuint); + if (showStoryboard && storyboard == null) + initializeStoryboard(); + + storyboard?.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); + storyboard?.FadeTo(showStoryboard && opacity > 0 ? 1 : 0, 200); + + Background?.FadeTo(!showStoryboard || !storyboardReplacesBackground ? opacity : 0, 800, Easing.OutQuint); } private void fadeOut() From f5368505abc9ff8d6d1ca97e90d647dea87097b2 Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 14 Sep 2017 18:56:01 +0200 Subject: [PATCH 27/96] Load the storyboard asynchronously if it wasn't loaded with the beatmap. --- osu.Game/Screens/Play/Player.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8a82c14d2d..1db83eab32 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -209,8 +209,9 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); + storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; if (showStoryboard) - initializeStoryboard(); + initializeStoryboard(false); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindRulesetContainer(RulesetContainer); @@ -227,15 +228,15 @@ namespace osu.Game.Screens.Play scoreProcessor.Failed += onFail; } - private void initializeStoryboard() + private void initializeStoryboard(bool asyncLoad) { var beatmap = Beatmap.Value.Beatmap; - storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; - - storyboardContainer.Add(storyboard = beatmap.Storyboard.CreateDrawable()); + storyboard = beatmap.Storyboard.CreateDrawable(); storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; storyboard.Masking = true; + + storyboardContainer.Add(asyncLoad ? new AsyncLoadWrapper(storyboard) { RelativeSizeAxes = Axes.Both } : (Drawable)storyboard); } public void Restart() @@ -348,7 +349,7 @@ namespace osu.Game.Screens.Play var opacity = 1 - (float)dimLevel; if (showStoryboard && storyboard == null) - initializeStoryboard(); + initializeStoryboard(true); storyboard?.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); storyboard?.FadeTo(showStoryboard && opacity > 0 ? 1 : 0, 200); From 757a159516299df37b4016d0624afb46cbeb13bc Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 15 Sep 2017 11:23:37 +0200 Subject: [PATCH 28/96] Display a non-parallax background at the appropriate size when storyboards do not replace it. --- osu.Game/Beatmaps/Beatmap.cs | 2 +- osu.Game/Screens/Play/Player.cs | 14 +++++++++----- .../Drawables/DrawableStoryboard.cs | 18 ++++++++++++++++++ osu.Game/Storyboards/IStoryboardElement.cs | 2 ++ osu.Game/Storyboards/Storyboard.cs | 2 ++ osu.Game/Storyboards/StoryboardSample.cs | 2 ++ osu.Game/Storyboards/StoryboardSprite.cs | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 44331d9679..ea3aa3cdff 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -53,7 +53,7 @@ namespace osu.Game.Beatmaps { get { - var backgroundPath = BeatmapInfo.BeatmapSet.Metadata.BackgroundFile?.ToLowerInvariant(); + var backgroundPath = BeatmapInfo.BeatmapSet.Metadata?.BackgroundFile?.ToLowerInvariant(); if (backgroundPath == null) return false; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1db83eab32..fd1eeaa395 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -71,7 +71,6 @@ namespace osu.Game.Screens.Play private Container storyboardContainer; private DrawableStoryboard storyboard; - private bool storyboardReplacesBackground; private HUDOverlay hudOverlay; private FailOverlay failOverlay; @@ -157,6 +156,7 @@ namespace osu.Game.Screens.Play { RelativeSizeAxes = Axes.Both, Clock = offsetClock, + Alpha = 0, }, pauseContainer = new PauseContainer { @@ -209,7 +209,6 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); - storyboardReplacesBackground = beatmap.StoryboardReplacesBackground; if (showStoryboard) initializeStoryboard(false); @@ -236,6 +235,8 @@ namespace osu.Game.Screens.Play storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; storyboard.Masking = true; + if (!beatmap.StoryboardReplacesBackground) + storyboard.BackgroundTexture = Beatmap.Value.Background; storyboardContainer.Add(asyncLoad ? new AsyncLoadWrapper(storyboard) { RelativeSizeAxes = Axes.Both } : (Drawable)storyboard); } @@ -351,10 +352,13 @@ namespace osu.Game.Screens.Play if (showStoryboard && storyboard == null) initializeStoryboard(true); - storyboard?.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboard?.FadeTo(showStoryboard && opacity > 0 ? 1 : 0, 200); + var beatmap = Beatmap.Value; + var storyboardVisible = showStoryboard && beatmap.Beatmap.Storyboard.HasDrawable; - Background?.FadeTo(!showStoryboard || !storyboardReplacesBackground ? opacity : 0, 800, Easing.OutQuint); + storyboardContainer.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); + storyboardContainer.FadeTo(storyboardVisible && opacity > 0 ? 1 : 0); + + Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, 800, Easing.OutQuint); } private void fadeOut() diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 73fb942eb2..5df88b342f 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.IO; @@ -14,6 +15,13 @@ namespace osu.Game.Storyboards.Drawables { public Storyboard Storyboard { get; private set; } + private readonly Background background; + public Texture BackgroundTexture + { + get { return background.Texture; } + set { background.Texture = value; } + } + private readonly Container content; protected override Container Content => content; @@ -43,6 +51,11 @@ namespace osu.Game.Storyboards.Drawables Anchor = Anchor.Centre; Origin = Anchor.Centre; + AddInternal(background = new Background + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); AddInternal(content = new Container { Size = new Vector2(640, 480), @@ -65,5 +78,10 @@ namespace osu.Game.Storyboards.Drawables foreach (var layer in Children) layer.Enabled = passing ? layer.Layer.EnabledWhenPassing : layer.Layer.EnabledWhenFailing; } + + private class Background : Sprite + { + protected override Vector2 DrawScale => Texture != null ? new Vector2(Parent.DrawHeight / Texture.DisplayHeight) : base.DrawScale; + } } } diff --git a/osu.Game/Storyboards/IStoryboardElement.cs b/osu.Game/Storyboards/IStoryboardElement.cs index d5fc86b0f7..74b6a8d8bc 100644 --- a/osu.Game/Storyboards/IStoryboardElement.cs +++ b/osu.Game/Storyboards/IStoryboardElement.cs @@ -8,6 +8,8 @@ namespace osu.Game.Storyboards public interface IStoryboardElement { string Path { get; } + bool IsDrawable { get; } + Drawable CreateDrawable(); } } diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 111cdd5d41..2e7188f28c 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -12,6 +12,8 @@ namespace osu.Game.Storyboards private readonly Dictionary layers = new Dictionary(); public IEnumerable Layers => layers.Values; + public bool HasDrawable => Layers.Any(l => l.Elements.Any(e => e.IsDrawable)); + public Storyboard() { layers.Add("Background", new StoryboardLayer("Background", 3)); diff --git a/osu.Game/Storyboards/StoryboardSample.cs b/osu.Game/Storyboards/StoryboardSample.cs index bcf6a4329d..8e769e7fcf 100644 --- a/osu.Game/Storyboards/StoryboardSample.cs +++ b/osu.Game/Storyboards/StoryboardSample.cs @@ -8,6 +8,8 @@ namespace osu.Game.Storyboards public class StoryboardSample : IStoryboardElement { public string Path { get; set; } + public bool IsDrawable => false; + public double Time; public float Volume; diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index 598167d720..349a59dee0 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -16,6 +16,8 @@ namespace osu.Game.Storyboards private readonly List triggers = new List(); public string Path { get; set; } + public bool IsDrawable => HasCommands; + public Anchor Origin; public Vector2 InitialPosition; From 291486a4d1750298656ecca2f484cfbdaaeda2dd Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 15 Sep 2017 13:35:41 +0200 Subject: [PATCH 29/96] Only create drawables for storyboard elements that will be visible. --- .../Drawables/DrawableStoryboardAnimation.cs | 10 ++-------- .../Storyboards/Drawables/DrawableStoryboardLayer.cs | 5 ++--- .../Storyboards/Drawables/DrawableStoryboardSprite.cs | 10 ++-------- osu.Game/Storyboards/StoryboardSample.cs | 5 ++++- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index d8b7d05ee9..9757756316 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -14,9 +14,6 @@ namespace osu.Game.Storyboards.Drawables { public StoryboardAnimation Animation { get; private set; } - protected override bool ShouldBeAlive => Animation.HasCommands && base.ShouldBeAlive; - public override bool RemoveWhenNotAlive => !Animation.HasCommands || base.RemoveWhenNotAlive; - public bool FlipH { get; set; } public bool FlipV { get; set; } @@ -59,11 +56,8 @@ namespace osu.Game.Storyboards.Drawables Position = animation.InitialPosition; Repeat = animation.LoopType == AnimationLoopType.LoopForever; - if (animation.HasCommands) - { - LifetimeStart = animation.StartTime; - LifetimeEnd = animation.EndTime; - } + LifetimeStart = animation.StartTime; + LifetimeEnd = animation.EndTime; } [BackgroundDependencyLoader] diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index 2b5db5b6fa..737704f6d0 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs @@ -28,9 +28,8 @@ namespace osu.Game.Storyboards.Drawables { foreach (var element in Layer.Elements) { - var drawable = element.CreateDrawable(); - if (drawable != null) - Add(drawable); + if (element.IsDrawable) + Add(element.CreateDrawable()); } } } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index 4b491fa008..9153b3e514 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -14,9 +14,6 @@ namespace osu.Game.Storyboards.Drawables { public StoryboardSprite Sprite { get; private set; } - protected override bool ShouldBeAlive => Sprite.HasCommands && base.ShouldBeAlive; - public override bool RemoveWhenNotAlive => !Sprite.HasCommands || base.RemoveWhenNotAlive; - public bool FlipH { get; set; } public bool FlipV { get; set; } @@ -58,11 +55,8 @@ namespace osu.Game.Storyboards.Drawables Origin = sprite.Origin; Position = sprite.InitialPosition; - if (sprite.HasCommands) - { - LifetimeStart = sprite.StartTime; - LifetimeEnd = sprite.EndTime; - } + LifetimeStart = sprite.StartTime; + LifetimeEnd = sprite.EndTime; } [BackgroundDependencyLoader] diff --git a/osu.Game/Storyboards/StoryboardSample.cs b/osu.Game/Storyboards/StoryboardSample.cs index 8e769e7fcf..e7a157c2f4 100644 --- a/osu.Game/Storyboards/StoryboardSample.cs +++ b/osu.Game/Storyboards/StoryboardSample.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; +using System; namespace osu.Game.Storyboards { @@ -21,6 +22,8 @@ namespace osu.Game.Storyboards } public Drawable CreateDrawable() - => null; + { + throw new InvalidOperationException(); + } } } From d9bde5ad5a0ff9bb509e1233df293c1492da1b65 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 15 Sep 2017 14:15:26 +0200 Subject: [PATCH 30/96] Fix TestCaseStoryboard Restart button. --- osu.Desktop.Tests/Visual/TestCaseStoryboard.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs index 878198e8d2..e236da2235 100644 --- a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs @@ -80,11 +80,15 @@ namespace osu.Desktop.Tests.Visual storyboardContainer.Remove(storyboard); var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true }; - decoupledClock.ChangeSource(working.Track); storyboardContainer.Clock = decoupledClock; - storyboardContainer.Add(storyboard = working.Beatmap.Storyboard.CreateDrawable()); + storyboard = working.Beatmap.Storyboard.CreateDrawable(); storyboard.Passing = false; + if (!working.Beatmap.StoryboardReplacesBackground) + storyboard.BackgroundTexture = working.Background; + + storyboardContainer.Add(storyboard); + decoupledClock.ChangeSource(working.Track); } } } From 5f6b300a3a86266426e183d256b9c4b93f1fd256 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 15 Sep 2017 15:12:16 +0200 Subject: [PATCH 31/96] Fix visual test crash when BeatmapInfo doesn't have a BeatmapSet. --- osu.Game/Beatmaps/Beatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index ea3aa3cdff..84db2f9943 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -53,7 +53,7 @@ namespace osu.Game.Beatmaps { get { - var backgroundPath = BeatmapInfo.BeatmapSet.Metadata?.BackgroundFile?.ToLowerInvariant(); + var backgroundPath = BeatmapInfo.BeatmapSet?.Metadata?.BackgroundFile?.ToLowerInvariant(); if (backgroundPath == null) return false; From 1bac1e2c0e48d5678a92ce6c2152924a01b5b4ce Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 15 Sep 2017 13:47:03 -0300 Subject: [PATCH 32/96] Make PreviewButton async. --- .../OnlineBeatmapSet/PreviewButton.cs | 112 ++++++++++++++---- 1 file changed, 88 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index 1dddf4a4a3..b12ec9c7ae 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -14,17 +14,38 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.OnlineBeatmapSet { public class PreviewButton : OsuClickableContainer { + private const float transition_duration = 500; + + private readonly Container audioWrapper; private readonly Box bg, progress; private readonly SpriteIcon icon; + private readonly LoadingAnimation loadingAnimation; - private AudioManager audio; 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 BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet { @@ -36,7 +57,6 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Playing = false; preview = null; - loadPreview(); } } @@ -49,22 +69,28 @@ namespace osu.Game.Overlays.OnlineBeatmapSet if (value == playing) return; playing = value; - if (progress == null) return; - - if (Playing) + if (preview == null) { - icon.Icon = FontAwesome.fa_stop; - progress.FadeIn(100); + loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet) + { + OnLoadComplete = d => + { + loading = false; - loadPreview(); - preview.Start(); - } - else - { - icon.Icon = FontAwesome.fa_play; - progress.FadeOut(100); - preview.Stop(); + if (d is AudioLoadWrapper) + { + preview = (d as AudioLoadWrapper).Preview; + Playing = Playing; + updatePlayingState(); + } + }, + }); + + return; } + + updatePlayingState(); } } @@ -74,6 +100,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Children = new Drawable[] { + audioWrapper = new Container(), bg = new Box { RelativeSizeAxes = Axes.Both, @@ -100,15 +127,19 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Size = new Vector2(18), Shadow = false, }, + loadingAnimation = new LoadingAnimation + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, }; Action = () => Playing = !Playing; } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { - this.audio = audio; progress.Colour = colours.Yellow; } @@ -116,10 +147,14 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { base.Update(); - if (Playing) + if (Playing && preview != null) { progress.Width = (float)(preview.CurrentTime / preview.Length); - if (preview.HasCompleted) Playing = false; + if (preview.HasCompleted) + { + Playing = false; + preview = null; + } } } @@ -141,16 +176,45 @@ namespace osu.Game.Overlays.OnlineBeatmapSet base.OnHoverLost(state); } - private void loadPreview() + private void updatePlayingState() { - if (preview == null || preview.HasCompleted && BeatmapSet != null) + if (preview == null) return; + + if (Playing) { - preview = audio.Track.Get(BeatmapSet.OnlineInfo.Preview); - preview.Volume.Value = 0.5; + icon.Icon = FontAwesome.fa_stop; + progress.FadeIn(100); + + preview.Seek(0); + preview.Start(); } else { - preview.Seek(0); + 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)) + { + Preview = audio.Track.Get(preview); + Preview.Volume.Value = 0.5; + } } } } From 7e30c55bf40865f75d7468c03e3e963f51862fd2 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 15 Sep 2017 13:54:16 -0300 Subject: [PATCH 33/96] CI fix. --- osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index b12ec9c7ae..8e93db8d19 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -78,12 +78,9 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { loading = false; - if (d is AudioLoadWrapper) - { - preview = (d as AudioLoadWrapper).Preview; - Playing = Playing; - updatePlayingState(); - } + preview = (d as AudioLoadWrapper).Preview; + Playing = Playing; + updatePlayingState(); }, }); From 2201fc745e4514cc9eff3104aa8f8e16e0585e86 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sat, 16 Sep 2017 13:15:16 +0200 Subject: [PATCH 34/96] Fix storyboard loops start time when none of their commands start at 0. --- osu.Game/Storyboards/CommandLoop.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index 02b5eb0122..0d8b57e46c 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -10,8 +10,8 @@ namespace osu.Game.Storyboards public double LoopStartTime; public int LoopCount; - public override double StartTime => LoopStartTime; - public override double EndTime => LoopStartTime + CommandsDuration * LoopCount; + public override double StartTime => LoopStartTime + CommandsStartTime; + public override double EndTime => StartTime + CommandsDuration * LoopCount; public CommandLoop(double startTime, int loopCount) { From e8462ac134d0026f65f419c570912cdd4cbead8a Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 00:47:55 +0200 Subject: [PATCH 35/96] Add option to disable cursor rotation. --- osu.Game/Configuration/OsuConfigManager.cs | 3 ++ osu.Game/Graphics/Cursor/MenuCursor.cs | 42 ++++++++++++------- .../Sections/Graphics/DetailSettings.cs | 16 +++++++ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 44a6af841c..42474ce80b 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -54,6 +54,8 @@ namespace osu.Game.Configuration // Graphics Set(OsuSetting.ShowFpsDisplay, false); + Set(OsuSetting.CursorRotation, true); + Set(OsuSetting.MenuParallax, true); Set(OsuSetting.SnakingInSliders, true); @@ -96,6 +98,7 @@ namespace osu.Game.Configuration AudioOffset, MenuMusic, MenuVoice, + CursorRotation, MenuParallax, BeatmapDetailTab, Username, diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 36f23d1ae9..c20bcce1a4 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -26,26 +26,28 @@ namespace osu.Game.Graphics.Cursor protected override bool OnMouseMove(InputState state) { - if (dragging) - { - Debug.Assert(state.Mouse.PositionMouseDown != null); + if (((Cursor)ActiveCursor).DragRotating) { + if (dragging) { + Debug.Assert (state.Mouse.PositionMouseDown != null); - // don't start rotating until we're moved a minimum distance away from the mouse down location, - // else it can have an annoying effect. - startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; + // don't start rotating until we're moved a minimum distance away from the mouse down location, + // else it can have an annoying effect. + startRotation |= Vector2Extensions.Distance (state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; - if (startRotation) - { - Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; - float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; + if (startRotation) { + Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; + float degrees = (float)MathHelper.RadiansToDegrees (Math.Atan2 (-offset.X, offset.Y)) + 24.3f; - // Always rotate in the direction of least distance - float diff = (degrees - ActiveCursor.Rotation) % 360; - if (diff < -180) diff += 360; - if (diff > 180) diff -= 360; - degrees = ActiveCursor.Rotation + diff; + // Always rotate in the direction of least distance + float diff = (degrees - ActiveCursor.Rotation) % 360; + if (diff < -180) + diff += 360; + if (diff > 180) + diff -= 360; + degrees = ActiveCursor.Rotation + diff; - ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); + ActiveCursor.RotateTo (degrees, 600, Easing.OutQuint); + } } } @@ -106,10 +108,14 @@ namespace osu.Game.Graphics.Cursor { private Container cursorContainer; private Bindable cursorScale; + public Bindable cursorRotate; + private const float base_scale = 0.15f; public Sprite AdditiveLayer; + public bool DragRotating; + public Cursor() { AutoSizeAxes = Axes.Both; @@ -143,6 +149,10 @@ namespace osu.Game.Graphics.Cursor cursorScale = config.GetBindable(OsuSetting.MenuCursorSize); cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale * base_scale); cursorScale.TriggerChange(); + + cursorRotate = config.GetBindable (OsuSetting.CursorRotation); + cursorRotate.ValueChanged += newValue => this.DragRotating = newValue; + cursorRotate.TriggerChange(); } } } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index c068da8129..3d44a30254 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -1,10 +1,26 @@ // 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.Configuration; + namespace osu.Game.Overlays.Settings.Sections.Graphics { public class DetailSettings : SettingsSubsection { protected override string Header => "Detail Settings"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new[] + { + new SettingsCheckbox + { + LabelText = "Rotate cursor when dragging", + Bindable = config.GetBindable(OsuSetting.CursorRotation) + }, + }; + } } } From bfe1febef211fe85bc046f51e79c36baa8cb1def Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:00:44 +0200 Subject: [PATCH 36/96] Fix field access + remove unneeded this --- osu.Game/Graphics/Cursor/MenuCursor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index c20bcce1a4..e3d30c5a7c 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -108,7 +108,7 @@ namespace osu.Game.Graphics.Cursor { private Container cursorContainer; private Bindable cursorScale; - public Bindable cursorRotate; + private Bindable cursorRotate; private const float base_scale = 0.15f; @@ -151,7 +151,7 @@ namespace osu.Game.Graphics.Cursor cursorScale.TriggerChange(); cursorRotate = config.GetBindable (OsuSetting.CursorRotation); - cursorRotate.ValueChanged += newValue => this.DragRotating = newValue; + cursorRotate.ValueChanged += newValue => DragRotating = newValue; cursorRotate.TriggerChange(); } } From 846838c621afa90299a0643a19f34b3eaec80f89 Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:14:33 +0200 Subject: [PATCH 37/96] Move to MenuCursor --- osu.Game/Graphics/Cursor/MenuCursor.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index e3d30c5a7c..bfa7b30fc2 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -20,13 +20,16 @@ namespace osu.Game.Graphics.Cursor { protected override Drawable CreateCursor() => new Cursor(); + private Bindable cursorRotate; + private bool dragRotating; + private bool dragging; private bool startRotation; protected override bool OnMouseMove(InputState state) { - if (((Cursor)ActiveCursor).DragRotating) { + if (dragRotating) { if (dragging) { Debug.Assert (state.Mouse.PositionMouseDown != null); @@ -104,18 +107,23 @@ namespace osu.Game.Graphics.Cursor ActiveCursor.ScaleTo(0, 500, Easing.In); } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) + { + cursorRotate = config.GetBindable (OsuSetting.CursorRotation); + cursorRotate.ValueChanged += newValue => dragRotating = newValue; + cursorRotate.TriggerChange(); + } + public class Cursor : Container { private Container cursorContainer; private Bindable cursorScale; - private Bindable cursorRotate; private const float base_scale = 0.15f; public Sprite AdditiveLayer; - public bool DragRotating; - public Cursor() { AutoSizeAxes = Axes.Both; @@ -149,10 +157,6 @@ namespace osu.Game.Graphics.Cursor cursorScale = config.GetBindable(OsuSetting.MenuCursorSize); cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale * base_scale); cursorScale.TriggerChange(); - - cursorRotate = config.GetBindable (OsuSetting.CursorRotation); - cursorRotate.ValueChanged += newValue => DragRotating = newValue; - cursorRotate.TriggerChange(); } } } From a8ada75633265a78cb1350336ed0d5f7c4db21a8 Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:28:02 +0200 Subject: [PATCH 38/96] CODE STYLE XD --- osu.Game/Graphics/Cursor/MenuCursor.cs | 39 ++++++++++++-------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index bfa7b30fc2..9f8808539d 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -21,7 +21,6 @@ namespace osu.Game.Graphics.Cursor protected override Drawable CreateCursor() => new Cursor(); private Bindable cursorRotate; - private bool dragRotating; private bool dragging; @@ -29,28 +28,27 @@ namespace osu.Game.Graphics.Cursor protected override bool OnMouseMove(InputState state) { - if (dragRotating) { - if (dragging) { - Debug.Assert (state.Mouse.PositionMouseDown != null); + if (cursorRotate && dragging) + { + Debug.Assert (state.Mouse.PositionMouseDown != null); - // don't start rotating until we're moved a minimum distance away from the mouse down location, - // else it can have an annoying effect. - startRotation |= Vector2Extensions.Distance (state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; + // don't start rotating until we're moved a minimum distance away from the mouse down location, + // else it can have an annoying effect. + startRotation |= Vector2Extensions.Distance (state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; - if (startRotation) { - Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; - float degrees = (float)MathHelper.RadiansToDegrees (Math.Atan2 (-offset.X, offset.Y)) + 24.3f; + if (startRotation) { + Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; + float degrees = (float)MathHelper.RadiansToDegrees (Math.Atan2 (-offset.X, offset.Y)) + 24.3f; - // Always rotate in the direction of least distance - float diff = (degrees - ActiveCursor.Rotation) % 360; - if (diff < -180) - diff += 360; - if (diff > 180) - diff -= 360; - degrees = ActiveCursor.Rotation + diff; + // Always rotate in the direction of least distance + float diff = (degrees - ActiveCursor.Rotation) % 360; + if (diff < -180) + diff += 360; + if (diff > 180) + diff -= 360; + degrees = ActiveCursor.Rotation + diff; - ActiveCursor.RotateTo (degrees, 600, Easing.OutQuint); - } + ActiveCursor.RotateTo (degrees, 600, Easing.OutQuint); } } @@ -108,10 +106,9 @@ namespace osu.Game.Graphics.Cursor } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) + private void load(OsuConfigManager config) { cursorRotate = config.GetBindable (OsuSetting.CursorRotation); - cursorRotate.ValueChanged += newValue => dragRotating = newValue; cursorRotate.TriggerChange(); } From 48008cd7e655673a0b8f87e4bd2c4e51ade8ca6a Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:34:56 +0200 Subject: [PATCH 39/96] ... --- osu.Game/Graphics/Cursor/MenuCursor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 9f8808539d..1b126edf4a 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -109,7 +109,6 @@ namespace osu.Game.Graphics.Cursor private void load(OsuConfigManager config) { cursorRotate = config.GetBindable (OsuSetting.CursorRotation); - cursorRotate.TriggerChange(); } public class Cursor : Container From a33dfbba25f41ad40a1adcc551d416f76849bac6 Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:40:38 +0200 Subject: [PATCH 40/96] Code reformat --- osu.Game/Graphics/Cursor/MenuCursor.cs | 81 ++++++++++++-------------- osu.Game/osu.Game.csproj | 18 ++++-- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 1b126edf4a..fe356b5dc1 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.Cursor { public class MenuCursor : CursorContainer { - protected override Drawable CreateCursor() => new Cursor(); + protected override Drawable CreateCursor () => new Cursor(); private Bindable cursorRotate; @@ -26,10 +26,9 @@ namespace osu.Game.Graphics.Cursor private bool startRotation; - protected override bool OnMouseMove(InputState state) + protected override bool OnMouseMove (InputState state) { - if (cursorRotate && dragging) - { + if (cursorRotate && dragging) { Debug.Assert (state.Mouse.PositionMouseDown != null); // don't start rotating until we're moved a minimum distance away from the mouse down location, @@ -52,61 +51,60 @@ namespace osu.Game.Graphics.Cursor } } - return base.OnMouseMove(state); + return base.OnMouseMove (state); } - protected override bool OnDragStart(InputState state) + protected override bool OnDragStart (InputState state) { dragging = true; - return base.OnDragStart(state); + return base.OnDragStart (state); } - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + protected override bool OnMouseDown (InputState state, MouseDownEventArgs args) { - ActiveCursor.Scale = new Vector2(1); - ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint); + ActiveCursor.Scale = new Vector2 (1); + ActiveCursor.ScaleTo (0.90f, 800, Easing.OutQuint); ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; - ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); - return base.OnMouseDown(state, args); + ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero (800, Easing.OutQuint); + return base.OnMouseDown (state, args); } - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + protected override bool OnMouseUp (InputState state, MouseUpEventArgs args) { - if (!state.Mouse.HasMainButtonPressed) - { + if (!state.Mouse.HasMainButtonPressed) { dragging = false; startRotation = false; - ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint); - ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); - ActiveCursor.ScaleTo(1, 500, Easing.OutElastic); + ((Cursor)ActiveCursor).AdditiveLayer.FadeOut (500, Easing.OutQuint); + ActiveCursor.RotateTo (0, 600 * (1 + Math.Abs (ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); + ActiveCursor.ScaleTo (1, 500, Easing.OutElastic); } - return base.OnMouseUp(state, args); + return base.OnMouseUp (state, args); } - protected override bool OnClick(InputState state) + protected override bool OnClick (InputState state) { - ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); + ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne (500, Easing.OutQuint); - return base.OnClick(state); + return base.OnClick (state); } - protected override void PopIn() + protected override void PopIn () { - ActiveCursor.FadeTo(1, 250, Easing.OutQuint); - ActiveCursor.ScaleTo(1, 400, Easing.OutQuint); + ActiveCursor.FadeTo (1, 250, Easing.OutQuint); + ActiveCursor.ScaleTo (1, 400, Easing.OutQuint); } - protected override void PopOut() + protected override void PopOut () { - ActiveCursor.FadeTo(0, 900, Easing.OutQuint); - ActiveCursor.ScaleTo(0, 500, Easing.In); + ActiveCursor.FadeTo (0, 900, Easing.OutQuint); + ActiveCursor.ScaleTo (0, 500, Easing.In); } [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load (OsuConfigManager config) { cursorRotate = config.GetBindable (OsuSetting.CursorRotation); } @@ -120,7 +118,7 @@ namespace osu.Game.Graphics.Cursor public Sprite AdditiveLayer; - public Cursor() + public Cursor () { AutoSizeAxes = Axes.Both; } @@ -128,30 +126,25 @@ namespace osu.Game.Graphics.Cursor [BackgroundDependencyLoader] private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) { - Children = new Drawable[] - { - cursorContainer = new Container - { + Children = new Drawable[] { + cursorContainer = new Container { AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Sprite - { - Texture = textures.Get(@"Cursor/menu-cursor"), + Children = new Drawable[] { + new Sprite { + Texture = textures.Get (@"Cursor/menu-cursor"), }, - AdditiveLayer = new Sprite - { + AdditiveLayer = new Sprite { Blending = BlendingMode.Additive, Colour = colour.Pink, Alpha = 0, - Texture = textures.Get(@"Cursor/menu-cursor-additive"), + Texture = textures.Get (@"Cursor/menu-cursor-additive"), }, } } }; - cursorScale = config.GetBindable(OsuSetting.MenuCursorSize); - cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale * base_scale); + cursorScale = config.GetBindable (OsuSetting.MenuCursorSize); + cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2 ((float)newScale * base_scale); cursorScale.TriggerChange(); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 92bcaf90f0..2bd7cbef77 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -1,5 +1,5 @@  - + Debug @@ -23,7 +23,6 @@ DEBUG;TRACE prompt 4 - false 6 @@ -33,7 +32,6 @@ TRACE prompt 4 - false @@ -561,11 +559,11 @@ - {c76bf5b3-985e-4d39-95fe-97c9c879b83a} + {C76BF5B3-985E-4D39-95FE-97C9C879B83A} osu.Framework - {d9a367c9-4c1a-489f-9b05-a0cea2b53b58} + {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58} osu.Game.Resources @@ -585,4 +583,14 @@ --> + + + + + + + + + + \ No newline at end of file From 3c00a7cc513f925f9e0a0ceabe9ee7b9f001086d Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 01:44:49 +0200 Subject: [PATCH 41/96] Reformat again... --- osu.Game/Graphics/Cursor/MenuCursor.cs | 94 ++++++++++++++------------ 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index fe356b5dc1..ae37aca6a4 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.Cursor { public class MenuCursor : CursorContainer { - protected override Drawable CreateCursor () => new Cursor(); + protected override Drawable CreateCursor() => new Cursor(); private Bindable cursorRotate; @@ -26,18 +26,20 @@ namespace osu.Game.Graphics.Cursor private bool startRotation; - protected override bool OnMouseMove (InputState state) + protected override bool OnMouseMove(InputState state) { - if (cursorRotate && dragging) { - Debug.Assert (state.Mouse.PositionMouseDown != null); + if (cursorRotate && dragging) + { + Debug.Assert(state.Mouse.PositionMouseDown != null); // don't start rotating until we're moved a minimum distance away from the mouse down location, // else it can have an annoying effect. - startRotation |= Vector2Extensions.Distance (state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; + startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; - if (startRotation) { + if (startRotation) + { Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; - float degrees = (float)MathHelper.RadiansToDegrees (Math.Atan2 (-offset.X, offset.Y)) + 24.3f; + float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; // Always rotate in the direction of least distance float diff = (degrees - ActiveCursor.Rotation) % 360; @@ -47,66 +49,67 @@ namespace osu.Game.Graphics.Cursor diff -= 360; degrees = ActiveCursor.Rotation + diff; - ActiveCursor.RotateTo (degrees, 600, Easing.OutQuint); + ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); } } - return base.OnMouseMove (state); + return base.OnMouseMove(state); } - protected override bool OnDragStart (InputState state) + protected override bool OnDragStart(InputState state) { dragging = true; - return base.OnDragStart (state); + return base.OnDragStart(state); } - protected override bool OnMouseDown (InputState state, MouseDownEventArgs args) + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - ActiveCursor.Scale = new Vector2 (1); - ActiveCursor.ScaleTo (0.90f, 800, Easing.OutQuint); + ActiveCursor.Scale = new Vector2(1); + ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint); ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; - ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero (800, Easing.OutQuint); - return base.OnMouseDown (state, args); + ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + return base.OnMouseDown(state, args); } - protected override bool OnMouseUp (InputState state, MouseUpEventArgs args) + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (!state.Mouse.HasMainButtonPressed) { + if (!state.Mouse.HasMainButtonPressed) + { dragging = false; startRotation = false; - ((Cursor)ActiveCursor).AdditiveLayer.FadeOut (500, Easing.OutQuint); - ActiveCursor.RotateTo (0, 600 * (1 + Math.Abs (ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); - ActiveCursor.ScaleTo (1, 500, Easing.OutElastic); + ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint); + ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); + ActiveCursor.ScaleTo(1, 500, Easing.OutElastic); } - return base.OnMouseUp (state, args); + return base.OnMouseUp(state, args); } - protected override bool OnClick (InputState state) + protected override bool OnClick(InputState state) { - ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne (500, Easing.OutQuint); + ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); - return base.OnClick (state); + return base.OnClick(state); } - protected override void PopIn () + protected override void PopIn() { - ActiveCursor.FadeTo (1, 250, Easing.OutQuint); - ActiveCursor.ScaleTo (1, 400, Easing.OutQuint); + ActiveCursor.FadeTo(1, 250, Easing.OutQuint); + ActiveCursor.ScaleTo(1, 400, Easing.OutQuint); } - protected override void PopOut () + protected override void PopOut() { - ActiveCursor.FadeTo (0, 900, Easing.OutQuint); - ActiveCursor.ScaleTo (0, 500, Easing.In); + ActiveCursor.FadeTo(0, 900, Easing.OutQuint); + ActiveCursor.ScaleTo(0, 500, Easing.In); } [BackgroundDependencyLoader] - private void load (OsuConfigManager config) + private void load(OsuConfigManager config) { - cursorRotate = config.GetBindable (OsuSetting.CursorRotation); + cursorRotate = config.GetBindable(OsuSetting.CursorRotation); } public class Cursor : Container @@ -118,7 +121,7 @@ namespace osu.Game.Graphics.Cursor public Sprite AdditiveLayer; - public Cursor () + public Cursor() { AutoSizeAxes = Axes.Both; } @@ -126,25 +129,30 @@ namespace osu.Game.Graphics.Cursor [BackgroundDependencyLoader] private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) { - Children = new Drawable[] { - cursorContainer = new Container { + Children = new Drawable[] + { + cursorContainer = new Container + { AutoSizeAxes = Axes.Both, - Children = new Drawable[] { - new Sprite { - Texture = textures.Get (@"Cursor/menu-cursor"), + Children = new Drawable[] + { + new Sprite + { + Texture = textures.Get(@"Cursor/menu-cursor"), }, - AdditiveLayer = new Sprite { + AdditiveLayer = new Sprite + { Blending = BlendingMode.Additive, Colour = colour.Pink, Alpha = 0, - Texture = textures.Get (@"Cursor/menu-cursor-additive"), + Texture = textures.Get(@"Cursor/menu-cursor-additive"), }, } } }; - cursorScale = config.GetBindable (OsuSetting.MenuCursorSize); - cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2 ((float)newScale * base_scale); + cursorScale = config.GetBindable(OsuSetting.MenuCursorSize); + cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale * base_scale); cursorScale.TriggerChange(); } } From 387705b2b63ec0d709eddb15cf26db5b40ae9ce8 Mon Sep 17 00:00:00 2001 From: gabixdev Date: Sun, 17 Sep 2017 19:43:53 +0200 Subject: [PATCH 42/96] revert csproj --- osu.Game/osu.Game.csproj | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2bd7cbef77..92bcaf90f0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -1,5 +1,5 @@  - + Debug @@ -23,6 +23,7 @@ DEBUG;TRACE prompt 4 + false 6 @@ -32,6 +33,7 @@ TRACE prompt 4 + false @@ -559,11 +561,11 @@ - {C76BF5B3-985E-4D39-95FE-97C9C879B83A} + {c76bf5b3-985e-4d39-95fe-97c9c879b83a} osu.Framework - {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58} + {d9a367c9-4c1a-489f-9b05-a0cea2b53b58} osu.Game.Resources @@ -583,14 +585,4 @@ --> - - - - - - - - - - \ No newline at end of file From 10efdffe49f449f3a7e2c522a49c029b73e556a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Sep 2017 15:33:15 +0900 Subject: [PATCH 43/96] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index e4101103d7..eef7736254 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit e4101103d744edc3c8c2abd4a715962bc2fb064e +Subproject commit eef77362549a7da60d1a7c27edca0f105ef0f280 From 67d3861226407269bc2a91f384f932b93907b1c4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 19 Sep 2017 23:09:08 +0900 Subject: [PATCH 44/96] Initial implementation of the EditorTimingTimeline in TestCaseEditorTimingTimeline Will probably rename this to MiniTimeline or something... But the basic structure is there plus most of functionality minus keyboard input. --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- .../Visual/TestCaseEditorTimingTimeline.cs | 371 ++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs diff --git a/osu-framework b/osu-framework index eef7736254..cdb031c3a8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit eef77362549a7da60d1a7c27edca0f105ef0f280 +Subproject commit cdb031c3a8ef693cd71458c5e19c68127ab72938 diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 0776669811..e031f25fa2 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps [JsonIgnore] public int[] Bookmarks { - get { return StoredBookmarks.Split(',').Select(int.Parse).ToArray(); } + get { return StoredBookmarks?.Split(',').Select(int.Parse).ToArray() ?? new int[0]; } set { StoredBookmarks = string.Join(",", value); } } diff --git a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs new file mode 100644 index 0000000000..da6a326b2e --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs @@ -0,0 +1,371 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Framework.Lists; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics; + +namespace osu.Game.Tests.Visual +{ + internal class TestCaseEditorTimingTimeline : OsuTestCase + { + public TestCaseEditorTimingTimeline() + { + Add(new TimingTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500, 50) + }); + } + + private class TimingTimeline : CompositeDrawable + { + private const float corner_radius = 5; + private const float contents_padding = 15; + private const float marker_bar_width = 2; + + private readonly Drawable background; + + private readonly Container markerContainer; + + private readonly Drawable timelineBar; + private readonly Drawable marker; + + private readonly Bindable beatmap = new Bindable(); + + public TimingTimeline() + { + Masking = true; + CornerRadius = 5; + + InternalChildren = new Drawable[] + { + background = new Box { RelativeSizeAxes = Axes.Both }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, + Children = new Drawable[] + { + markerContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Child = marker = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Triangle + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Scale = new Vector2(1, -1), + Size = new Vector2(10, 5), + }, + new Triangle + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(10, 5) + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Width = 2, + EdgeSmoothness = new Vector2(1, 0) + } + } + } + }, + new ControlPointTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + new BookmarkTimeline + { + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + timelineBar = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Size = new Vector2(5) + }, + new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + EdgeSmoothness = new Vector2(0, 1), + }, + new Circle + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Size = new Vector2(5) + }, + } + }, + new BreakTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.25f + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, OsuColour colours) + { + background.Colour = colours.Gray1; + marker.Colour = colours.Red; + timelineBar.Colour = colours.Gray5; + + beatmap.BindTo(osuGame.Beatmap); + + markerContainer.RelativeChildSize = new Vector2((float)beatmap.Value.Track.Length, 1); + } + + protected override bool OnDragStart(InputState state) => true; + + protected override bool OnDrag(InputState state) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + protected override bool OnDragEnd(InputState state) => true; + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + private void seekToPosition(Vector2 screenPosition) + { + float markerPos = MathHelper.Clamp(markerContainer.ToLocalSpace(screenPosition).X, 0, markerContainer.DrawWidth); + seekTo(markerPos / markerContainer.DrawWidth * beatmap.Value.Track.Length); + } + + private void seekTo(double time) => beatmap.Value.Track.Seek(time); + + protected override void Update() + { + base.Update(); + + marker.X = (float)beatmap.Value.Track.CurrentTime; + } + + private class ControlPointTimeline : Timeline + { + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, OsuColour colours) + { + var beatmap = osuGame.Beatmap.Value; + if (beatmap == null) + return; + + ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; + + cpi.TimingPoints.ForEach(addTimingPoint); + + // Consider all non-timing points as the same type + cpi.SoundPoints.Select(c => (ControlPoint)c) + .Concat(cpi.EffectPoints) + .Concat(cpi.DifficultyPoints) + .Distinct() + // Non-timing points should not be added where there are timing points + .Where(c => cpi.TimingPointAt(c.Time).Time != c.Time) + .ForEach(addNonTimingPoint); + } + + private void addTimingPoint(ControlPoint controlPoint) => Add(new TimingPointVisualisation(controlPoint)); + private void addNonTimingPoint(ControlPoint controlPoint) => Add(new NonTimingPointVisualisation(controlPoint)); + + private class TimingPointVisualisation : ControlPointVisualisation + { + public TimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.YellowDark; + } + + private class NonTimingPointVisualisation : ControlPointVisualisation + { + public NonTimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Green; + } + + private abstract class ControlPointVisualisation : PointVisualisation + { + public readonly ControlPoint ControlPoint; + + public ControlPointVisualisation(ControlPoint controlPoint) + : base(controlPoint.Time) + { + ControlPoint = controlPoint; + } + } + } + + private class BookmarkTimeline : Timeline + { + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + var beatmap = osuGame.Beatmap.Value; + if (beatmap == null) + return; + + foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) + Add(new BookmarkVisualisation(bookmark)); + } + + private class BookmarkVisualisation : PointVisualisation + { + public BookmarkVisualisation(double startTime) + : base(startTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Blue; + } + } + + private class BreakTimeline : Timeline + { + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + var beatmap = osuGame.Beatmap.Value; + if (beatmap == null) + return; + + foreach (var breakPeriod in beatmap.Beatmap.Breaks) + Add(new BreakVisualisation(breakPeriod)); + } + + private class BreakVisualisation : DurationVisualisation + { + public BreakVisualisation(BreakPeriod breakPeriod) + : base(breakPeriod.StartTime, breakPeriod.EndTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Yellow; + } + } + + private abstract class Timeline : CompositeDrawable + { + private readonly Container timeline; + + public Timeline() + { + AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + var beatmap = osuGame.Beatmap.Value; + if (beatmap == null) + return; + + timeline.RelativeChildSize = new Vector2((float)beatmap.Track.Length, 1); + } + + protected void Add(PointVisualisation visualisation) => timeline.Add(visualisation); + + protected void Add(DurationVisualisation visualisation) => timeline.Add(visualisation); + } + + private class PointVisualisation : Box + { + public readonly double StartTime; + + public PointVisualisation(double startTime) + { + StartTime = startTime; + + Origin = Anchor.TopCentre; + + RelativeSizeAxes = Axes.Y; + Width = 1; + EdgeSmoothness = new Vector2(1, 0); + + RelativePositionAxes = Axes.X; + X = (float)startTime; + } + } + + private class DurationVisualisation : Container + { + public readonly double StartTime; + public readonly double EndTIme; + + public DurationVisualisation(double startTime, double endTime) + { + StartTime = startTime; + EndTIme = endTime; + + Masking = true; + CornerRadius = corner_radius; + + RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.Both; + X = (float)startTime; + Width = (float)(endTime - startTime); + + AddInternal(new Box { RelativeSizeAxes = Axes.Both }); + } + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2d286fe1b8..3ca7f393f1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -733,6 +733,7 @@ + From 120446e4a72ddef607693884800d07b01547dfc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 20 Sep 2017 14:31:17 +0900 Subject: [PATCH 45/96] Ensure only one dialog is being displayed by the SongSelect footer at a time Fixes #1208 --- osu.Game/Screens/Select/Footer.cs | 26 +++++++++++++++++++++++ osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index bb6d16da0f..6636dbde76 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using OpenTK; using OpenTK.Graphics; @@ -58,6 +59,31 @@ namespace osu.Game.Screens.Select Action = action, }); + private readonly List overlays = new List(); + + /// Text on the button. + /// Colour of the button. + /// Hotkey of the button. + /// The to be toggled by this button. + /// + /// Higher depth to be put on the left, and lower to be put on the right. + /// Notice this is different to ! + /// + public void AddButton(string text, Color4 colour, OverlayContainer overlay, Key? hotkey = null, float depth = 0) + { + overlays.Add(overlay); + AddButton(text, colour, () => + { + foreach (var o in overlays) + { + if (o == overlay) + overlay.ToggleVisibility(); + else + overlay.Hide(); + } + }, hotkey, depth); + } + private void updateModeLight() => modeLight.FadeColour(buttons.FirstOrDefault(b => b.IsHovered)?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, Easing.OutQuint); public Footer() diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 7e03707d18..e0a3693371 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load(OsuColour colours) { - Footer.AddButton(@"mods", colours.Yellow, modSelect.ToggleVisibility, Key.F1, float.MaxValue); + Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1); BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 84457b77a7..836ed465c3 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -164,7 +164,7 @@ namespace osu.Game.Screens.Select if (Footer != null) { Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); - Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3); + Footer.AddButton(@"options", colours.Blue, BeatmapOptions, Key.F3); BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue); } From 01c3818ea050d1e93fdf743732c296a0fc520b17 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 15:40:27 +0900 Subject: [PATCH 46/96] Make EditorTimingTimeline support beatmap changes --- .../Visual/TestCaseEditorTimingTimeline.cs | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs index da6a326b2e..b6df81148e 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.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 System.Collections.Generic; using System.Linq; using OpenTK; @@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Lists; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; @@ -158,7 +160,8 @@ namespace osu.Game.Tests.Visual beatmap.BindTo(osuGame.Beatmap); - markerContainer.RelativeChildSize = new Vector2((float)beatmap.Value.Track.Length, 1); + markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); + beatmap.ValueChanged += b => markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); } protected override bool OnDragStart(InputState state) => true; @@ -194,13 +197,8 @@ namespace osu.Game.Tests.Visual private class ControlPointTimeline : Timeline { - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, OsuColour colours) + protected override void LoadBeatmap(WorkingBeatmap beatmap) { - var beatmap = osuGame.Beatmap.Value; - if (beatmap == null) - return; - ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; cpi.TimingPoints.ForEach(addTimingPoint); @@ -254,13 +252,8 @@ namespace osu.Game.Tests.Visual private class BookmarkTimeline : Timeline { - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + protected override void LoadBeatmap(WorkingBeatmap beatmap) { - var beatmap = osuGame.Beatmap.Value; - if (beatmap == null) - return; - foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) Add(new BookmarkVisualisation(bookmark)); } @@ -279,13 +272,8 @@ namespace osu.Game.Tests.Visual private class BreakTimeline : Timeline { - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + protected override void LoadBeatmap(WorkingBeatmap beatmap) { - var beatmap = osuGame.Beatmap.Value; - if (beatmap == null) - return; - foreach (var breakPeriod in beatmap.Beatmap.Breaks) Add(new BreakVisualisation(breakPeriod)); } @@ -314,16 +302,21 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) { - var beatmap = osuGame.Beatmap.Value; - if (beatmap == null) - return; + osuGame.Beatmap.ValueChanged += b => + { + timeline.Clear(); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); + LoadBeatmap(b); + }; - timeline.RelativeChildSize = new Vector2((float)beatmap.Track.Length, 1); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); + LoadBeatmap(osuGame.Beatmap); } protected void Add(PointVisualisation visualisation) => timeline.Add(visualisation); - protected void Add(DurationVisualisation visualisation) => timeline.Add(visualisation); + + protected abstract void LoadBeatmap(WorkingBeatmap beatmap); } private class PointVisualisation : Box From 252121968d7b1840cd545407daded52cdef0da7c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 15:40:42 +0900 Subject: [PATCH 47/96] Actually load a beatmap for TestCaseEditorTimingTimeline --- .../Tests/Visual/TestCaseEditorTimingTimeline.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs index b6df81148e..14dc19da57 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs @@ -34,6 +34,21 @@ namespace osu.Game.Tests.Visual }); } + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, BeatmapManager beatmaps) + { + BeatmapSetInfo setInfo = null; + + var sets = beatmaps.GetAllUsableBeatmapSets(false); + if (sets.Count > 0) + setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); + + if (setInfo == null) + return; + + osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + } + private class TimingTimeline : CompositeDrawable { private const float corner_radius = 5; From fd278256ad6b6f3330bae8a6cd4f1c8391c86175 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 15:50:32 +0900 Subject: [PATCH 48/96] EditorTimingTimeline -> EditorMiniTimeline --- ...TimingTimeline.cs => TestCaseEditorMiniTimeline.cs} | 10 +++++----- osu.Game/osu.Game.csproj | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename osu.Game/Tests/Visual/{TestCaseEditorTimingTimeline.cs => TestCaseEditorMiniTimeline.cs} (96%) diff --git a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs similarity index 96% rename from osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs rename to osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs index 14dc19da57..ecf6d90cef 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorTimingTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs @@ -22,11 +22,11 @@ using osu.Game.Graphics; namespace osu.Game.Tests.Visual { - internal class TestCaseEditorTimingTimeline : OsuTestCase + internal class TestCaseEditorMiniTimeline : OsuTestCase { - public TestCaseEditorTimingTimeline() + public TestCaseEditorMiniTimeline() { - Add(new TimingTimeline + Add(new MiniTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); } - private class TimingTimeline : CompositeDrawable + private class MiniTimeline : CompositeDrawable { private const float corner_radius = 5; private const float contents_padding = 15; @@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual private readonly Bindable beatmap = new Bindable(); - public TimingTimeline() + public MiniTimeline() { Masking = true; CornerRadius = 5; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3ca7f393f1..facbc525e5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -733,7 +733,7 @@ - + From 01d84893a09022b4c0d4feb504f35d2764c8c7ae Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 15:55:23 +0900 Subject: [PATCH 49/96] Cleanup + commenting --- .../Visual/TestCaseEditorMiniTimeline.cs | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs index ecf6d90cef..f33c7301d5 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs @@ -49,6 +49,9 @@ namespace osu.Game.Tests.Visual osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); } + /// + /// The timeline that sits at the bottom of the editor. + /// private class MiniTimeline : CompositeDrawable { private const float corner_radius = 5; @@ -180,21 +183,23 @@ namespace osu.Game.Tests.Visual } protected override bool OnDragStart(InputState state) => true; - + protected override bool OnDragEnd(InputState state) => true; protected override bool OnDrag(InputState state) { seekToPosition(state.Mouse.NativeState.Position); return true; } - protected override bool OnDragEnd(InputState state) => true; - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { seekToPosition(state.Mouse.NativeState.Position); return true; } + /// + /// Seeks the to the time closest to a position on the screen relative to the . + /// + /// The position in screen coordinates. private void seekToPosition(Vector2 screenPosition) { float markerPos = MathHelper.Clamp(markerContainer.ToLocalSpace(screenPosition).X, 0, markerContainer.DrawWidth); @@ -206,10 +211,12 @@ namespace osu.Game.Tests.Visual protected override void Update() { base.Update(); - marker.X = (float)beatmap.Value.Track.CurrentTime; } + /// + /// The part of the timeline that displays the control points. + /// private class ControlPointTimeline : Timeline { protected override void LoadBeatmap(WorkingBeatmap beatmap) @@ -265,6 +272,9 @@ namespace osu.Game.Tests.Visual } } + /// + /// The part of the timeline that displays bookmarks. + /// private class BookmarkTimeline : Timeline { protected override void LoadBeatmap(WorkingBeatmap beatmap) @@ -285,6 +295,9 @@ namespace osu.Game.Tests.Visual } } + /// + /// The part of the timeline that displays breaks in the song. + /// private class BreakTimeline : Timeline { protected override void LoadBeatmap(WorkingBeatmap beatmap) @@ -305,6 +318,9 @@ namespace osu.Game.Tests.Visual } } + /// + /// Represents a part of the editor timeline. + /// private abstract class Timeline : CompositeDrawable { private readonly Container timeline; @@ -334,6 +350,9 @@ namespace osu.Game.Tests.Visual protected abstract void LoadBeatmap(WorkingBeatmap beatmap); } + /// + /// Represents a singular point on a . + /// private class PointVisualisation : Box { public readonly double StartTime; @@ -353,6 +372,9 @@ namespace osu.Game.Tests.Visual } } + /// + /// Represents a spanning point on a . + /// private class DurationVisualisation : Container { public readonly double StartTime; From 967bfa404e5335569bd36050e8d20d78d6751bee Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 16:40:37 +0900 Subject: [PATCH 50/96] Generate a set beatmap instead of using the available beatmaps --- .../Visual/TestCaseEditorMiniTimeline.cs | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs index f33c7301d5..4e81ee1990 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs @@ -7,11 +7,13 @@ using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Lists; using osu.Framework.MathUtils; @@ -24,8 +26,13 @@ namespace osu.Game.Tests.Visual { internal class TestCaseEditorMiniTimeline : OsuTestCase { + private const int length = 60000; + private readonly Random random; + public TestCaseEditorMiniTimeline() { + random = new Random(1337); + Add(new MiniTimeline { Anchor = Anchor.Centre, @@ -37,16 +44,50 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame, BeatmapManager beatmaps) { - BeatmapSetInfo setInfo = null; + var beatmap = new Beatmap(); - var sets = beatmaps.GetAllUsableBeatmapSets(false); - if (sets.Count > 0) - setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); + for (int i = 0; i < random.Next(1, 10); i++) + beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { Time = random.Next(0, length) }); - if (setInfo == null) - return; + for (int i = 0; i < random.Next(1, 5); i++) + beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint { Time = random.Next(0, length) }); - osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + for (int i = 0; i < random.Next(1, 5); i++) + beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint { Time = random.Next(0, length) }); + + for (int i = 0; i < random.Next(1, 5); i++) + beatmap.ControlPointInfo.SoundPoints.Add(new SoundControlPoint { Time = random.Next(0, length) }); + + beatmap.BeatmapInfo.Bookmarks = new int[random.Next(10, 30)]; + for (int i = 0; i < beatmap.BeatmapInfo.Bookmarks.Length; i++) + beatmap.BeatmapInfo.Bookmarks[i] = random.Next(0, length); + + osuGame.Beatmap.Value = new TestWorkingBeatmap(beatmap); + } + + private class TestWorkingBeatmap : WorkingBeatmap + { + private readonly Beatmap beatmap; + + public TestWorkingBeatmap(Beatmap beatmap) + : base(beatmap.BeatmapInfo) + { + this.beatmap = beatmap; + } + + protected override Texture GetBackground() => null; + + protected override Beatmap GetBeatmap() => beatmap; + + protected override Track GetTrack() => new TestTrack(); + + private class TestTrack : TrackVirtual + { + public TestTrack() + { + Length = length; + } + } } /// From 5978668d2b7387f09ce58783d86cc3ee569fa7f6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 16:48:30 +0900 Subject: [PATCH 51/96] Mini -> Summary --- ...iTimeline.cs => TestCaseEditorSummaryTimeline.cs} | 12 ++++++------ osu.Game/osu.Game.csproj | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) rename osu.Game/Tests/Visual/{TestCaseEditorMiniTimeline.cs => TestCaseEditorSummaryTimeline.cs} (95%) diff --git a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs similarity index 95% rename from osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs rename to osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index 4e81ee1990..0f170e7a6e 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorMiniTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -24,16 +24,16 @@ using osu.Game.Graphics; namespace osu.Game.Tests.Visual { - internal class TestCaseEditorMiniTimeline : OsuTestCase + internal class TestCaseEditorSummaryTimeline : OsuTestCase { private const int length = 60000; private readonly Random random; - public TestCaseEditorMiniTimeline() + public TestCaseEditorSummaryTimeline() { random = new Random(1337); - Add(new MiniTimeline + Add(new SummaryTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual /// /// The timeline that sits at the bottom of the editor. /// - private class MiniTimeline : CompositeDrawable + private class SummaryTimeline : CompositeDrawable { private const float corner_radius = 5; private const float contents_padding = 15; @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual private readonly Bindable beatmap = new Bindable(); - public MiniTimeline() + public SummaryTimeline() { Masking = true; CornerRadius = 5; @@ -238,7 +238,7 @@ namespace osu.Game.Tests.Visual } /// - /// Seeks the to the time closest to a position on the screen relative to the . + /// Seeks the to the time closest to a position on the screen relative to the . /// /// The position in screen coordinates. private void seekToPosition(Vector2 screenPosition) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index facbc525e5..fde6133aac 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -733,7 +733,7 @@ - + From 3da3ef1a504bf6c571a97bdc56171b5628cc9cd6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 16:53:01 +0900 Subject: [PATCH 52/96] CI fixes --- .../Visual/TestCaseEditorSummaryTimeline.cs | 31 +++++-------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index 0f170e7a6e..9c9c7e963b 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -2,10 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.Linq; using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Configuration; @@ -15,8 +13,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; using osu.Framework.Input; -using osu.Framework.Lists; -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; @@ -42,7 +38,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, BeatmapManager beatmaps) + private void load(OsuGameBase osuGame) { var beatmap = new Beatmap(); @@ -113,14 +109,14 @@ namespace osu.Game.Tests.Visual Masking = true; CornerRadius = 5; - InternalChildren = new Drawable[] + InternalChildren = new[] { background = new Box { RelativeSizeAxes = Axes.Both }, new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, - Children = new Drawable[] + Children = new[] { markerContainer = new Container { @@ -303,12 +299,9 @@ namespace osu.Game.Tests.Visual private abstract class ControlPointVisualisation : PointVisualisation { - public readonly ControlPoint ControlPoint; - - public ControlPointVisualisation(ControlPoint controlPoint) + protected ControlPointVisualisation(ControlPoint controlPoint) : base(controlPoint.Time) { - ControlPoint = controlPoint; } } } @@ -366,7 +359,7 @@ namespace osu.Game.Tests.Visual { private readonly Container timeline; - public Timeline() + protected Timeline() { AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); } @@ -396,12 +389,8 @@ namespace osu.Game.Tests.Visual /// private class PointVisualisation : Box { - public readonly double StartTime; - - public PointVisualisation(double startTime) + protected PointVisualisation(double startTime) { - StartTime = startTime; - Origin = Anchor.TopCentre; RelativeSizeAxes = Axes.Y; @@ -418,14 +407,8 @@ namespace osu.Game.Tests.Visual /// private class DurationVisualisation : Container { - public readonly double StartTime; - public readonly double EndTIme; - - public DurationVisualisation(double startTime, double endTime) + protected DurationVisualisation(double startTime, double endTime) { - StartTime = startTime; - EndTIme = endTime; - Masking = true; CornerRadius = corner_radius; From f9568619e7a71655192b56556b4a30f8c93f2dc7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 16:59:03 +0900 Subject: [PATCH 53/96] Move SummaryTimeline into /Edit/Components/SummaryTimeline --- .../Edit/Components/SummaryTimeline.cs | 356 ++++++++++++++++++ .../Visual/TestCaseEditorSummaryTimeline.cs | 340 +---------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 361 insertions(+), 336 deletions(-) create mode 100644 osu.Game/Screens/Edit/Components/SummaryTimeline.cs diff --git a/osu.Game/Screens/Edit/Components/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/SummaryTimeline.cs new file mode 100644 index 0000000000..ffb54ba7b1 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/SummaryTimeline.cs @@ -0,0 +1,356 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +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.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Components +{ + /// + /// The timeline that sits at the bottom of the editor. + /// + public class SummaryTimeline : CompositeDrawable + { + private const float corner_radius = 5; + private const float contents_padding = 15; + private const float marker_bar_width = 2; + + private readonly Drawable background; + + private readonly Container markerContainer; + + private readonly Drawable timelineBar; + private readonly Drawable marker; + + private readonly Bindable beatmap = new Bindable(); + + public SummaryTimeline() + { + Masking = true; + CornerRadius = 5; + + InternalChildren = new[] + { + background = new Box { RelativeSizeAxes = Axes.Both }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, + Children = new[] + { + markerContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Child = marker = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Triangle + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Scale = new Vector2(1, -1), + Size = new Vector2(10, 5), + }, + new Triangle + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(10, 5) + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Width = 2, + EdgeSmoothness = new Vector2(1, 0) + } + } + } + }, + new ControlPointTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + new BookmarkTimeline + { + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + timelineBar = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Size = new Vector2(5) + }, + new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + EdgeSmoothness = new Vector2(0, 1), + }, + new Circle + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Size = new Vector2(5) + }, + } + }, + new BreakTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.25f + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, OsuColour colours) + { + background.Colour = colours.Gray1; + marker.Colour = colours.Red; + timelineBar.Colour = colours.Gray5; + + beatmap.BindTo(osuGame.Beatmap); + + markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); + beatmap.ValueChanged += b => markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); + } + + protected override bool OnDragStart(InputState state) => true; + protected override bool OnDragEnd(InputState state) => true; + protected override bool OnDrag(InputState state) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + /// + /// Seeks the to the time closest to a position on the screen relative to the . + /// + /// The position in screen coordinates. + private void seekToPosition(Vector2 screenPosition) + { + float markerPos = MathHelper.Clamp(markerContainer.ToLocalSpace(screenPosition).X, 0, markerContainer.DrawWidth); + seekTo(markerPos / markerContainer.DrawWidth * beatmap.Value.Track.Length); + } + + private void seekTo(double time) => beatmap.Value.Track.Seek(time); + + protected override void Update() + { + base.Update(); + marker.X = (float)beatmap.Value.Track.CurrentTime; + } + + /// + /// The part of the timeline that displays the control points. + /// + private class ControlPointTimeline : Timeline + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; + + cpi.TimingPoints.ForEach(addTimingPoint); + + // Consider all non-timing points as the same type + cpi.SoundPoints.Select(c => (ControlPoint)c) + .Concat(cpi.EffectPoints) + .Concat(cpi.DifficultyPoints) + .Distinct() + // Non-timing points should not be added where there are timing points + .Where(c => cpi.TimingPointAt(c.Time).Time != c.Time) + .ForEach(addNonTimingPoint); + } + + private void addTimingPoint(ControlPoint controlPoint) => Add(new TimingPointVisualisation(controlPoint)); + private void addNonTimingPoint(ControlPoint controlPoint) => Add(new NonTimingPointVisualisation(controlPoint)); + + private class TimingPointVisualisation : ControlPointVisualisation + { + public TimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.YellowDark; + } + + private class NonTimingPointVisualisation : ControlPointVisualisation + { + public NonTimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Green; + } + + private abstract class ControlPointVisualisation : PointVisualisation + { + protected ControlPointVisualisation(ControlPoint controlPoint) + : base(controlPoint.Time) + { + } + } + } + + /// + /// The part of the timeline that displays bookmarks. + /// + private class BookmarkTimeline : Timeline + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) + Add(new BookmarkVisualisation(bookmark)); + } + + private class BookmarkVisualisation : PointVisualisation + { + public BookmarkVisualisation(double startTime) + : base(startTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Blue; + } + } + + /// + /// The part of the timeline that displays breaks in the song. + /// + private class BreakTimeline : Timeline + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + foreach (var breakPeriod in beatmap.Beatmap.Breaks) + Add(new BreakVisualisation(breakPeriod)); + } + + private class BreakVisualisation : DurationVisualisation + { + public BreakVisualisation(BreakPeriod breakPeriod) + : base(breakPeriod.StartTime, breakPeriod.EndTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Yellow; + } + } + + /// + /// Represents a part of the editor timeline. + /// + private abstract class Timeline : CompositeDrawable + { + private readonly Container timeline; + + protected Timeline() + { + AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + osuGame.Beatmap.ValueChanged += b => + { + timeline.Clear(); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); + LoadBeatmap(b); + }; + + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); + LoadBeatmap(osuGame.Beatmap); + } + + protected void Add(PointVisualisation visualisation) => timeline.Add(visualisation); + protected void Add(DurationVisualisation visualisation) => timeline.Add(visualisation); + + protected abstract void LoadBeatmap(WorkingBeatmap beatmap); + } + + /// + /// Represents a singular point on a . + /// + private class PointVisualisation : Box + { + protected PointVisualisation(double startTime) + { + Origin = Anchor.TopCentre; + + RelativeSizeAxes = Axes.Y; + Width = 1; + EdgeSmoothness = new Vector2(1, 0); + + RelativePositionAxes = Axes.X; + X = (float)startTime; + } + } + + /// + /// Represents a spanning point on a . + /// + private class DurationVisualisation : Container + { + protected DurationVisualisation(double startTime, double endTime) + { + Masking = true; + CornerRadius = corner_radius; + + RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.Both; + X = (float)startTime; + Width = (float)(endTime - startTime); + + AddInternal(new Box { RelativeSizeAxes = Axes.Both }); + } + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index 9c9c7e963b..ee7f54f771 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using OpenTK; using osu.Framework.Allocation; @@ -17,6 +18,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components; namespace osu.Game.Tests.Visual { @@ -25,6 +27,8 @@ namespace osu.Game.Tests.Visual private const int length = 60000; private readonly Random random; + public override IReadOnlyList RequiredTypes => new Type[] { typeof(SummaryTimeline) }; + public TestCaseEditorSummaryTimeline() { random = new Random(1337); @@ -85,341 +89,5 @@ namespace osu.Game.Tests.Visual } } } - - /// - /// The timeline that sits at the bottom of the editor. - /// - private class SummaryTimeline : CompositeDrawable - { - private const float corner_radius = 5; - private const float contents_padding = 15; - private const float marker_bar_width = 2; - - private readonly Drawable background; - - private readonly Container markerContainer; - - private readonly Drawable timelineBar; - private readonly Drawable marker; - - private readonly Bindable beatmap = new Bindable(); - - public SummaryTimeline() - { - Masking = true; - CornerRadius = 5; - - InternalChildren = new[] - { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, - Children = new[] - { - markerContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = marker = new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Triangle - { - Anchor = Anchor.TopCentre, - Origin = Anchor.BottomCentre, - Scale = new Vector2(1, -1), - Size = new Vector2(10, 5), - }, - new Triangle - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(10, 5) - }, - new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Y, - Width = 2, - EdgeSmoothness = new Vector2(1, 0) - } - } - } - }, - new ControlPointTimeline - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - new BookmarkTimeline - { - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - timelineBar = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Size = new Vector2(5) - }, - new Box - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - EdgeSmoothness = new Vector2(0, 1), - }, - new Circle - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Size = new Vector2(5) - }, - } - }, - new BreakTimeline - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.25f - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, OsuColour colours) - { - background.Colour = colours.Gray1; - marker.Colour = colours.Red; - timelineBar.Colour = colours.Gray5; - - beatmap.BindTo(osuGame.Beatmap); - - markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); - beatmap.ValueChanged += b => markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); - } - - protected override bool OnDragStart(InputState state) => true; - protected override bool OnDragEnd(InputState state) => true; - protected override bool OnDrag(InputState state) - { - seekToPosition(state.Mouse.NativeState.Position); - return true; - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - seekToPosition(state.Mouse.NativeState.Position); - return true; - } - - /// - /// Seeks the to the time closest to a position on the screen relative to the . - /// - /// The position in screen coordinates. - private void seekToPosition(Vector2 screenPosition) - { - float markerPos = MathHelper.Clamp(markerContainer.ToLocalSpace(screenPosition).X, 0, markerContainer.DrawWidth); - seekTo(markerPos / markerContainer.DrawWidth * beatmap.Value.Track.Length); - } - - private void seekTo(double time) => beatmap.Value.Track.Seek(time); - - protected override void Update() - { - base.Update(); - marker.X = (float)beatmap.Value.Track.CurrentTime; - } - - /// - /// The part of the timeline that displays the control points. - /// - private class ControlPointTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; - - cpi.TimingPoints.ForEach(addTimingPoint); - - // Consider all non-timing points as the same type - cpi.SoundPoints.Select(c => (ControlPoint)c) - .Concat(cpi.EffectPoints) - .Concat(cpi.DifficultyPoints) - .Distinct() - // Non-timing points should not be added where there are timing points - .Where(c => cpi.TimingPointAt(c.Time).Time != c.Time) - .ForEach(addNonTimingPoint); - } - - private void addTimingPoint(ControlPoint controlPoint) => Add(new TimingPointVisualisation(controlPoint)); - private void addNonTimingPoint(ControlPoint controlPoint) => Add(new NonTimingPointVisualisation(controlPoint)); - - private class TimingPointVisualisation : ControlPointVisualisation - { - public TimingPointVisualisation(ControlPoint controlPoint) - : base(controlPoint) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.YellowDark; - } - - private class NonTimingPointVisualisation : ControlPointVisualisation - { - public NonTimingPointVisualisation(ControlPoint controlPoint) - : base(controlPoint) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Green; - } - - private abstract class ControlPointVisualisation : PointVisualisation - { - protected ControlPointVisualisation(ControlPoint controlPoint) - : base(controlPoint.Time) - { - } - } - } - - /// - /// The part of the timeline that displays bookmarks. - /// - private class BookmarkTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) - Add(new BookmarkVisualisation(bookmark)); - } - - private class BookmarkVisualisation : PointVisualisation - { - public BookmarkVisualisation(double startTime) - : base(startTime) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Blue; - } - } - - /// - /// The part of the timeline that displays breaks in the song. - /// - private class BreakTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - foreach (var breakPeriod in beatmap.Beatmap.Breaks) - Add(new BreakVisualisation(breakPeriod)); - } - - private class BreakVisualisation : DurationVisualisation - { - public BreakVisualisation(BreakPeriod breakPeriod) - : base(breakPeriod.StartTime, breakPeriod.EndTime) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Yellow; - } - } - - /// - /// Represents a part of the editor timeline. - /// - private abstract class Timeline : CompositeDrawable - { - private readonly Container timeline; - - protected Timeline() - { - AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); - } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - osuGame.Beatmap.ValueChanged += b => - { - timeline.Clear(); - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); - LoadBeatmap(b); - }; - - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); - LoadBeatmap(osuGame.Beatmap); - } - - protected void Add(PointVisualisation visualisation) => timeline.Add(visualisation); - protected void Add(DurationVisualisation visualisation) => timeline.Add(visualisation); - - protected abstract void LoadBeatmap(WorkingBeatmap beatmap); - } - - /// - /// Represents a singular point on a . - /// - private class PointVisualisation : Box - { - protected PointVisualisation(double startTime) - { - Origin = Anchor.TopCentre; - - RelativeSizeAxes = Axes.Y; - Width = 1; - EdgeSmoothness = new Vector2(1, 0); - - RelativePositionAxes = Axes.X; - X = (float)startTime; - } - } - - /// - /// Represents a spanning point on a . - /// - private class DurationVisualisation : Container - { - protected DurationVisualisation(double startTime, double endTime) - { - Masking = true; - CornerRadius = corner_radius; - - RelativePositionAxes = Axes.X; - RelativeSizeAxes = Axes.Both; - X = (float)startTime; - Width = (float)(endTime - startTime); - - AddInternal(new Box { RelativeSizeAxes = Axes.Both }); - } - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fde6133aac..768d46dce4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -604,6 +604,7 @@ + From 7588f1b6caee6f0f0e81a269ff9c49d51fd274f6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 17:09:38 +0900 Subject: [PATCH 54/96] Add SummaryTimeline to Editor --- osu.Game/Screens/Edit/Editor.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index be9098e3be..04f45d9a34 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -13,6 +13,8 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; +using osu.Game.Screens.Edit.Components; +using OpenTK; namespace osu.Game.Screens.Edit { @@ -189,6 +191,23 @@ namespace osu.Game.Screens.Edit } } }); + + Add(new FillFlowContainer + { + Name = "Bottom bar", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 60, + Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new[] + { + new SummaryTimeline { RelativeSizeAxes = Axes.Both } + } + }); + } protected override void OnResuming(Screen last) From 58b09a161f65a5e053c35b1ada6264cbc1929dda Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 17:16:12 +0900 Subject: [PATCH 55/96] CI fixes --- .../Tests/Visual/TestCaseEditorSummaryTimeline.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index ee7f54f771..68c34269f8 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -3,22 +3,14 @@ using System; using System.Collections.Generic; -using System.Linq; -using OpenTK; using osu.Framework.Allocation; using osu.Framework.Audio.Track; -using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; -using osu.Framework.Input; +using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Timing; -using osu.Game.Graphics; using osu.Game.Screens.Edit.Components; +using OpenTK; namespace osu.Game.Tests.Visual { @@ -27,7 +19,7 @@ namespace osu.Game.Tests.Visual private const int length = 60000; private readonly Random random; - public override IReadOnlyList RequiredTypes => new Type[] { typeof(SummaryTimeline) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(SummaryTimeline) }; public TestCaseEditorSummaryTimeline() { From 7168e8fd99e20dc43b7f80e78540ebdd089d5b7f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 18:16:03 +0900 Subject: [PATCH 56/96] Improve layout of bottom bar in the Editor --- osu.Game/Screens/Edit/Editor.cs | 44 +++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 04f45d9a34..b482061cd8 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -15,17 +15,18 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; using osu.Game.Screens.Edit.Components; using OpenTK; +using osu.Framework.Allocation; namespace osu.Game.Screens.Edit { - internal class Editor : ScreenWhiteBox + internal class Editor : OsuScreen { - protected override IEnumerable PossibleChildren => new[] { typeof(EditSongSelect) }; - protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); internal override bool ShowOverlays => false; + private readonly Box bottomBackground; + public Editor() { Add(new Container @@ -192,22 +193,45 @@ namespace osu.Game.Screens.Edit } }); - Add(new FillFlowContainer + Add(new Container { - Name = "Bottom bar", Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, Height = 60, - Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new[] + Children = new Drawable[] { - new SummaryTimeline { RelativeSizeAxes = Axes.Both } + bottomBackground = new Box { RelativeSizeAxes = Axes.Both }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, + Child = new FillFlowContainer + { + Name = "Bottom bar", + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new[] + { + new SummaryTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Width = 0.65f + } + } + } + } } }); + } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + bottomBackground.Colour = colours.Gray2; } protected override void OnResuming(Screen last) From e65a17ad96697b051b41744c77f588b573f6dfde Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 20 Sep 2017 18:40:41 +0900 Subject: [PATCH 57/96] Remove redundant usings --- osu.Game/Screens/Edit/Editor.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b482061cd8..c91ea9d686 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -1,12 +1,9 @@ // 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.Graphics; using osu.Framework.Screens; using osu.Game.Screens.Backgrounds; -using osu.Game.Screens.Select; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 46af17f00c4b98b66ba0efaa647085c132abf9a4 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 21 Sep 2017 14:46:51 -0300 Subject: [PATCH 58/96] Fix preview button potential null ref. --- osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index 8e93db8d19..dacb1c3743 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -76,11 +76,14 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { OnLoadComplete = d => { - loading = false; + if (d is AudioLoadWrapper) + { + loading = false; - preview = (d as AudioLoadWrapper).Preview; - Playing = Playing; - updatePlayingState(); + preview = ((AudioLoadWrapper)d).Preview; + Playing = Playing; + updatePlayingState(); + } }, }); From 01e70f9bef9efc6d5d49ba68429f0ce3ac212a12 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 21 Sep 2017 14:53:42 -0300 Subject: [PATCH 59/96] Change type check to safe cast. --- osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs index dacb1c3743..b8673e2a77 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs @@ -76,14 +76,11 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { OnLoadComplete = d => { - if (d is AudioLoadWrapper) - { - loading = false; + loading = false; - preview = ((AudioLoadWrapper)d).Preview; - Playing = Playing; - updatePlayingState(); - } + preview = (d as AudioLoadWrapper)?.Preview; + Playing = Playing; + updatePlayingState(); }, }); From 8438ea1267c28a2e86b210d099fb8a83dc904c6f Mon Sep 17 00:00:00 2001 From: gabixdev Date: Thu, 21 Sep 2017 22:11:35 +0200 Subject: [PATCH 60/96] Fix formatting ;_; --- osu.Game/Graphics/Cursor/MenuCursor.cs | 8 ++------ .../Overlays/Settings/Sections/Graphics/DetailSettings.cs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index ae37aca6a4..da117a94c1 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -21,7 +21,6 @@ namespace osu.Game.Graphics.Cursor protected override Drawable CreateCursor() => new Cursor(); private Bindable cursorRotate; - private bool dragging; private bool startRotation; @@ -43,10 +42,8 @@ namespace osu.Game.Graphics.Cursor // Always rotate in the direction of least distance float diff = (degrees - ActiveCursor.Rotation) % 360; - if (diff < -180) - diff += 360; - if (diff > 180) - diff -= 360; + if (diff < -180) diff += 360; + if (diff > 180) diff -= 360; degrees = ActiveCursor.Rotation + diff; ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); @@ -116,7 +113,6 @@ namespace osu.Game.Graphics.Cursor { private Container cursorContainer; private Bindable cursorScale; - private const float base_scale = 0.15f; public Sprite AdditiveLayer; diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index 3d44a30254..0e348f3791 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Game.Configuration; - namespace osu.Game.Overlays.Settings.Sections.Graphics { public class DetailSettings : SettingsSubsection From 31e26364a6c5dda84e294ff60e88820ef7c9d69f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 01:47:24 +0200 Subject: [PATCH 61/96] Initial implementation of chat commands --- .../Online/API/Requests/PostMessageRequest.cs | 3 +- osu.Game/Online/Chat/Message.cs | 3 ++ osu.Game/Overlays/Chat/ChatLine.cs | 7 ++-- osu.Game/Overlays/ChatOverlay.cs | 33 ++++++++++++++++--- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/API/Requests/PostMessageRequest.cs b/osu.Game/Online/API/Requests/PostMessageRequest.cs index 52269d9fe8..f0c7cb9a9b 100644 --- a/osu.Game/Online/API/Requests/PostMessageRequest.cs +++ b/osu.Game/Online/API/Requests/PostMessageRequest.cs @@ -23,6 +23,7 @@ namespace osu.Game.Online.API.Requests req.Method = HttpMethod.POST; req.AddParameter(@"target_type", message.TargetType.GetDescription()); req.AddParameter(@"target_id", message.TargetId.ToString()); + req.AddParameter(@"is_action", message.IsAction.ToString().ToLower()); req.AddParameter(@"message", message.Content); return req; @@ -30,4 +31,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => @"chat/messages"; } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 509861868a..79b5c4fc1a 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -23,6 +23,9 @@ namespace osu.Game.Online.Chat [JsonProperty(@"target_id")] public int TargetId; + [JsonProperty(@"is_action")] + public bool IsAction; + [JsonProperty(@"timestamp")] public DateTimeOffset Timestamp; diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index cac0ce01ae..fc18049491 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -62,6 +62,7 @@ namespace osu.Game.Overlays.Chat public const float LEFT_PADDING = message_padding + padding * 2; private const float padding = 15; + private const float padding_action = 5; private const float message_padding = 200; private const float text_size = 20; @@ -183,7 +184,7 @@ namespace osu.Game.Overlays.Chat { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = message_padding + padding }, + Padding = new MarginPadding { Left = message_padding + (message.IsAction ? padding_action : padding) }, Children = new Drawable[] { contentFlow = new OsuTextFlowContainer(t => { t.TextSize = text_size; }) @@ -194,6 +195,8 @@ namespace osu.Game.Overlays.Chat } } }; + if (message.IsAction) + contentFlow.Colour = senderHasBackground ? OsuColour.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; updateMessageContent(); FinishTransforms(true); @@ -205,7 +208,7 @@ namespace osu.Game.Overlays.Chat timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); + username.Text = (message.IsAction ? "*" : "") + $@"{message.Sender.Username}" + (senderHasBackground || message.IsAction ? "" : ":"); contentFlow.Text = message.Content; } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 7c28bdea4d..ef755b6239 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -465,7 +465,7 @@ namespace osu.Game.Overlays textbox.Text = string.Empty; - if (string.IsNullOrEmpty(postText)) + if (string.IsNullOrWhiteSpace(postText)) return; var target = currentChannel; @@ -478,11 +478,35 @@ namespace osu.Game.Overlays return; } + bool isAction = false; + if (postText[0] == '/') { - // TODO: handle commands - target.AddNewMessages(new ErrorMessage("Chat commands are not supported yet!")); - return; + postText = postText.Substring(1); + string commandKeyword = postText.Split(' ')[0]; + + switch (commandKeyword) + { + case "me": + + if (!postText.StartsWith("me ") || string.IsNullOrWhiteSpace(postText.Substring(3))) + { + currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); + return; + } + + isAction = true; + postText = postText.Substring(3); + break; + + case "help": + currentChannel.AddNewMessages(new ErrorMessage("Supported commands: /help, /me [action]")); + return; + + default: + currentChannel.AddNewMessages(new ErrorMessage($@"""/{commandKeyword}"" is not supported! For a list of supported commands see /help")); + return; + } } var message = new LocalEchoMessage @@ -491,6 +515,7 @@ namespace osu.Game.Overlays Timestamp = DateTimeOffset.Now, TargetType = TargetType.Channel, //TODO: read this from channel TargetId = target.Id, + IsAction = isAction, Content = postText }; From dce577f92ae1bd61b6f536a24fe5fb61d2ad7694 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 11:30:01 +0200 Subject: [PATCH 62/96] Updated design --- osu.Game/Overlays/Chat/ChatLine.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index fc18049491..9345cd010e 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -62,8 +62,8 @@ namespace osu.Game.Overlays.Chat public const float LEFT_PADDING = message_padding + padding * 2; private const float padding = 15; - private const float padding_action = 5; private const float message_padding = 200; + private const float action_padding = 3; private const float text_size = 20; private Color4 customUsernameColour; @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Chat { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = message_padding + (message.IsAction ? padding_action : padding) }, + Padding = new MarginPadding { Left = message_padding + padding }, Children = new Drawable[] { contentFlow = new OsuTextFlowContainer(t => { t.TextSize = text_size; }) @@ -208,8 +208,14 @@ namespace osu.Game.Overlays.Chat timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = (message.IsAction ? "*" : "") + $@"{message.Sender.Username}" + (senderHasBackground || message.IsAction ? "" : ":"); - contentFlow.Text = message.Content; + username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); + + contentFlow.Clear(); + if (message.IsAction) + contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); + contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic" ); + if (message.IsAction) + contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); } private class MessageSender : ClickableContainer, IHasContextMenu From 3e8941f8e1662215901e8e5294feddbcca3dcedf Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 11:35:07 +0200 Subject: [PATCH 63/96] Fix chat message style for non action messages --- osu.Game/Overlays/Chat/ChatLine.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 9345cd010e..ef1ab5f9db 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -213,7 +213,11 @@ namespace osu.Game.Overlays.Chat contentFlow.Clear(); if (message.IsAction) contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); - contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic" ); + contentFlow.AddText(message.Content, sprite => + { + if (message.IsAction) + sprite.Font = @"Exo2.0-MediumItalic"; + }); if (message.IsAction) contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); } From dc5c046d4be5b2bb8f04f2105161fc09814b6f35 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 14:33:20 +0200 Subject: [PATCH 64/96] Fixed wrong action message color --- osu.Game/Overlays/Chat/ChatLine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index ef1ab5f9db..d17371fae1 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -195,8 +195,8 @@ namespace osu.Game.Overlays.Chat } } }; - if (message.IsAction) - contentFlow.Colour = senderHasBackground ? OsuColour.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; + if (message.IsAction && senderHasBackground) + contentFlow.Colour = OsuColour.FromHex(message.Sender.Colour); updateMessageContent(); FinishTransforms(true); From 29707788f9dc62b76ea8c58644495f1a31b7b5c3 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:29:04 +0200 Subject: [PATCH 65/96] Code formatting --- osu.Game/Overlays/Chat/ChatLine.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index d17371fae1..4db6bdf5e4 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -210,16 +210,16 @@ namespace osu.Game.Overlays.Chat timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); - contentFlow.Clear(); if (message.IsAction) - contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); - contentFlow.AddText(message.Content, sprite => { - if (message.IsAction) - sprite.Font = @"Exo2.0-MediumItalic"; - }); - if (message.IsAction) + contentFlow.Clear(); + contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); + contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic"); contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); + } + else + contentFlow.Text = message.Content; + } private class MessageSender : ClickableContainer, IHasContextMenu From 18c26a85ba15af8213e3310f9501a4fecfd58551 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:30:07 +0200 Subject: [PATCH 66/96] Added an infoMessage class to represent system messages that aren't errors --- osu.Game/Online/Chat/ErrorMessage.cs | 17 ++++------------- osu.Game/Online/Chat/InfoMessage.cs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Online/Chat/InfoMessage.cs diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index 48557ca648..fdb77e328f 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -6,20 +6,11 @@ using osu.Game.Users; namespace osu.Game.Online.Chat { - public class ErrorMessage : Message + public class ErrorMessage : InfoMessage { - private static int errorId = -1; - - public ErrorMessage(string message) : base(errorId--) + public ErrorMessage(string message) : base(message) { - Timestamp = DateTimeOffset.Now; - Content = message; - - Sender = new User - { - Username = @"system", - Colour = @"ff0000", - }; + Sender.Colour = @"ff0000"; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Chat/InfoMessage.cs b/osu.Game/Online/Chat/InfoMessage.cs new file mode 100644 index 0000000000..edadfe351d --- /dev/null +++ b/osu.Game/Online/Chat/InfoMessage.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Users; + +namespace osu.Game.Online.Chat +{ + public class InfoMessage : Message + { + private static int infoID = -1; + + public InfoMessage(string message) : base(infoID--) + { + Timestamp = DateTimeOffset.Now; + Content = message; + + Sender = new User + { + Username = @"system", + Colour = @"0000ff", + }; + } + } +} From 0a279167613a09ecae11c64908a103a8a9c94094 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:31:30 +0200 Subject: [PATCH 67/96] Added infoMessage class to the project, use the class for the /help command and handle command parameter better --- osu.Game/Overlays/ChatOverlay.cs | 17 ++++++++++++----- osu.Game/osu.Game.csproj | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index ef755b6239..93f8a3c2b7 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -482,25 +482,25 @@ namespace osu.Game.Overlays if (postText[0] == '/') { - postText = postText.Substring(1); - string commandKeyword = postText.Split(' ')[0]; + string unhandeledParameters = postText.Substring(1); + string commandKeyword = cutFirstParameter(ref unhandeledParameters); switch (commandKeyword) { case "me": - if (!postText.StartsWith("me ") || string.IsNullOrWhiteSpace(postText.Substring(3))) + if (string.IsNullOrWhiteSpace(unhandeledParameters)) { currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); return; } isAction = true; - postText = postText.Substring(3); + postText = unhandeledParameters; break; case "help": - currentChannel.AddNewMessages(new ErrorMessage("Supported commands: /help, /me [action]")); + currentChannel.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]")); return; default: @@ -528,6 +528,13 @@ namespace osu.Game.Overlays api.Queue(req); } + private string cutFirstParameter(ref string parameters) + { + string result = parameters.Split(' ')[0]; + parameters = result.Length == parameters.Length ? "" : parameters.Substring(result.Length + 1); + return result; + } + private void transformChatHeightTo(double newChatHeight, double duration = 0, Easing easing = Easing.None) { this.TransformTo(this.PopulateTransform(new TransformChatHeight(), newChatHeight, duration, easing)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2d286fe1b8..1679c53ff9 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -372,6 +372,7 @@ + From 02bc42991179fb4409faa889d4400f110ea1700f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:37:17 +0200 Subject: [PATCH 68/96] CI fix --- osu.Game/Online/Chat/ErrorMessage.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index fdb77e328f..0bf18fda39 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -1,9 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using osu.Game.Users; - namespace osu.Game.Online.Chat { public class ErrorMessage : InfoMessage From 34fb6ccdf5484c2a361f4977e48670a77ce83640 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 16:17:03 +0200 Subject: [PATCH 69/96] Removed generic parameter function --- osu.Game/Overlays/ChatOverlay.cs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 93f8a3c2b7..24fc322199 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -482,21 +482,22 @@ namespace osu.Game.Overlays if (postText[0] == '/') { - string unhandeledParameters = postText.Substring(1); - string commandKeyword = cutFirstParameter(ref unhandeledParameters); + string[] parameters = postText.Substring(1).Split(new[] { ' ' }, 2); + string command = parameters[0]; + string content = parameters.Length == 2 ? parameters[1] : string.Empty; - switch (commandKeyword) + switch (command) { case "me": - if (string.IsNullOrWhiteSpace(unhandeledParameters)) + if (string.IsNullOrWhiteSpace(content)) { currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); return; } isAction = true; - postText = unhandeledParameters; + postText = content; break; case "help": @@ -504,7 +505,7 @@ namespace osu.Game.Overlays return; default: - currentChannel.AddNewMessages(new ErrorMessage($@"""/{commandKeyword}"" is not supported! For a list of supported commands see /help")); + currentChannel.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help")); return; } } @@ -528,13 +529,6 @@ namespace osu.Game.Overlays api.Queue(req); } - private string cutFirstParameter(ref string parameters) - { - string result = parameters.Split(' ')[0]; - parameters = result.Length == parameters.Length ? "" : parameters.Substring(result.Length + 1); - return result; - } - private void transformChatHeightTo(double newChatHeight, double duration = 0, Easing easing = Easing.None) { this.TransformTo(this.PopulateTransform(new TransformChatHeight(), newChatHeight, duration, easing)); From e04526222cbf4f4024f680855b329b3251b84340 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Fri, 22 Sep 2017 22:47:26 +0200 Subject: [PATCH 70/96] URL encode beatmap filename --- osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs index 15e20a3d55..934ef7ffa2 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.API.Requests { private readonly BeatmapInfo beatmap; - private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={beatmap.Path}"; + private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; public GetBeatmapDetailsRequest(BeatmapInfo beatmap) { From 442259d9e0b66d6a14a05bbd4ec36aee229f996b Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 23 Sep 2017 19:47:23 +0800 Subject: [PATCH 71/96] Fix overlay toggling in song select. --- osu.Game/Screens/Select/Footer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 6636dbde76..00f311e522 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -77,9 +77,9 @@ namespace osu.Game.Screens.Select foreach (var o in overlays) { if (o == overlay) - overlay.ToggleVisibility(); + o.ToggleVisibility(); else - overlay.Hide(); + o.Hide(); } }, hotkey, depth); } From d277952e0f72a7f3d78837d99627b002c4e5e0e2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 00:42:46 +0800 Subject: [PATCH 72/96] Use DateTimeOffset.ToUnixTime --- osu.Game/Online/API/APIRequest.cs | 4 ++-- osu.Game/Online/API/OAuthToken.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 307afb2d2b..bf70529ead 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -70,7 +70,7 @@ namespace osu.Game.Online.API protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}"; - private double remainingTime => Math.Max(0, Timeout - (DateTime.Now.TotalMilliseconds() - (startTime ?? 0))); + private double remainingTime => Math.Max(0, Timeout - (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - (startTime ?? 0))); public bool ExceededTimeout => remainingTime == 0; @@ -96,7 +96,7 @@ namespace osu.Game.Online.API return; if (startTime == null) - startTime = DateTime.Now.TotalMilliseconds(); + startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); if (remainingTime <= 0) throw new TimeoutException(@"API request timeout hit"); diff --git a/osu.Game/Online/API/OAuthToken.cs b/osu.Game/Online/API/OAuthToken.cs index 1788adbf56..477bcdd9b8 100644 --- a/osu.Game/Online/API/OAuthToken.cs +++ b/osu.Game/Online/API/OAuthToken.cs @@ -22,12 +22,12 @@ namespace osu.Game.Online.API { get { - return AccessTokenExpiry - DateTime.Now.ToUnixTimestamp(); + return AccessTokenExpiry - DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } set { - AccessTokenExpiry = DateTime.Now.AddSeconds(value).ToUnixTimestamp(); + AccessTokenExpiry = DateTimeOffset.Now.AddSeconds(value).ToUnixTimeSeconds(); } } From c5aebf6401fd9c28002c4fdeaaf6ef8e9edfaad2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 03:23:31 +0800 Subject: [PATCH 73/96] Use TimeSpan to represent time. --- osu.Game/Online/API/APIRequest.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index bf70529ead..a354d77bc5 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -70,13 +70,11 @@ namespace osu.Game.Online.API protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}"; - private double remainingTime => Math.Max(0, Timeout - (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - (startTime ?? 0))); + private double remainingTime => Math.Max(0, Timeout - (DateTimeOffset.UtcNow - (startTime ?? DateTimeOffset.MinValue)).TotalMilliseconds); public bool ExceededTimeout => remainingTime == 0; - private double? startTime; - - public double StartTime => startTime ?? -1; + private DateTimeOffset? startTime; protected APIAccess API; protected WebRequest WebRequest; @@ -96,7 +94,7 @@ namespace osu.Game.Online.API return; if (startTime == null) - startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + startTime = DateTimeOffset.UtcNow; if (remainingTime <= 0) throw new TimeoutException(@"API request timeout hit"); From 87c8278139127acdba2fddc5e4416c8a33317d6e Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 03:45:46 +0800 Subject: [PATCH 74/96] Use Array.Empty. --- osu.Game/IO/Legacy/SerializationReader.cs | 4 ++-- osu.Game/Overlays/Mods/ModButton.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/IO/Legacy/SerializationReader.cs b/osu.Game/IO/Legacy/SerializationReader.cs index bad143fa6c..c7ea884821 100644 --- a/osu.Game/IO/Legacy/SerializationReader.cs +++ b/osu.Game/IO/Legacy/SerializationReader.cs @@ -49,7 +49,7 @@ namespace osu.Game.IO.Legacy int len = ReadInt32(); if (len > 0) return ReadBytes(len); if (len < 0) return null; - return new byte[0]; + return Array.Empty(); } /// Reads a char array from the buffer, handling nulls and the array length. @@ -58,7 +58,7 @@ namespace osu.Game.IO.Legacy int len = ReadInt32(); if (len > 0) return ReadChars(len); if (len < 0) return null; - return new char[0]; + return Array.Empty(); } /// Reads a DateTime from the buffer. diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 3ca4a204a5..6bfe70d873 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -127,7 +127,7 @@ namespace osu.Game.Overlays.Mods if (mod == null) { - Mods = new Mod[0]; + Mods = Array.Empty(); Alpha = 0; } else From 2b11ecec1371088a5ebc4049004c5ff7ad0c4cf2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 06:03:52 +0800 Subject: [PATCH 75/96] Remove usings to extensions. --- osu.Game/Online/API/APIRequest.cs | 1 - osu.Game/Online/API/OAuthToken.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index a354d77bc5..37903f924f 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osu.Framework.Extensions; using osu.Framework.IO.Network; namespace osu.Game.Online.API diff --git a/osu.Game/Online/API/OAuthToken.cs b/osu.Game/Online/API/OAuthToken.cs index 477bcdd9b8..2abd7b6c1f 100644 --- a/osu.Game/Online/API/OAuthToken.cs +++ b/osu.Game/Online/API/OAuthToken.cs @@ -4,7 +4,6 @@ using System; using System.Globalization; using Newtonsoft.Json; -using osu.Framework.Extensions; namespace osu.Game.Online.API { From a1b313620c9adb9b996d92ef4fdcfc1854706e9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 23 Sep 2017 19:22:53 +0800 Subject: [PATCH 76/96] Set a busy timeout when creating an SQLIteConnection --- osu.Game/OsuGameBase.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 448dccdd72..8e7bfa8a76 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -82,6 +82,13 @@ namespace osu.Game protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + private SQLiteConnection createConnection() + { + var conn = Host.Storage.GetDatabase(@"client"); + conn.BusyTimeout = new TimeSpan(TimeSpan.TicksPerSecond * 10); + return conn; + } + private SQLiteConnection connection; [BackgroundDependencyLoader] @@ -90,8 +97,7 @@ namespace osu.Game dependencies.Cache(this); dependencies.Cache(LocalConfig); - connection = Host.Storage.GetDatabase(@"client"); - + connection = createConnection(); connection.CreateTable(); dependencies.Cache(API = new APIAccess From 1e6c4807912beeb29302735aa07c747898773966 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 11:52:01 +0800 Subject: [PATCH 77/96] Add back missing tests --- .../Beatmaps/Formats/OsuLegacyDecoderTest.cs | 146 +++ .../Beatmaps/IO/ImportBeatmapTest.cs | 164 +++ .../Beatmaps/IO/OszArchiveReaderTest.cs | 83 ++ osu.Game.Tests/OpenTK.dll.config | 25 + osu.Game.Tests/Resources/Resource.cs | 20 + .../Soleily - Renatus (Gamu) [Insane].osu | 1002 +++++++++++++++++ osu.Game.Tests/app.config | 11 + osu.Game.Tests/osu.Game.Tests.csproj | 103 ++ osu.Game.Tests/packages.config | 11 + osu.sln | 8 + 10 files changed, 1573 insertions(+) create mode 100644 osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs create mode 100644 osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs create mode 100644 osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs create mode 100644 osu.Game.Tests/OpenTK.dll.config create mode 100644 osu.Game.Tests/Resources/Resource.cs create mode 100644 osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu create mode 100644 osu.Game.Tests/app.config create mode 100644 osu.Game.Tests/osu.Game.Tests.csproj create mode 100644 osu.Game.Tests/packages.config diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs new file mode 100644 index 0000000000..da3b448f74 --- /dev/null +++ b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs @@ -0,0 +1,146 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.IO; +using NUnit.Framework; +using OpenTK; +using OpenTK.Graphics; +using osu.Game.Beatmaps.Formats; +using osu.Game.Tests.Resources; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Rulesets.Objects.Types; + +namespace osu.Game.Tests.Beatmaps.Formats +{ + [TestFixture] + public class OsuLegacyDecoderTest + { + [Test] + public void TestDecodeMetadata() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmap = decoder.Decode(new StreamReader(stream)); + var meta = beatmap.BeatmapInfo.Metadata; + Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + Assert.AreEqual("Soleily", meta.Artist); + Assert.AreEqual("Soleily", meta.ArtistUnicode); + Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); + Assert.AreEqual("Gamu", meta.Author); + Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile); + Assert.AreEqual(164471, meta.PreviewTime); + Assert.AreEqual(string.Empty, meta.Source); + Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags); + Assert.AreEqual("Renatus", meta.Title); + Assert.AreEqual("Renatus", meta.TitleUnicode); + } + } + + [Test] + public void TestDecodeGeneral() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmapInfo = decoder.Decode(new StreamReader(stream)).BeatmapInfo; + Assert.AreEqual(0, beatmapInfo.AudioLeadIn); + Assert.AreEqual(false, beatmapInfo.Countdown); + Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); + Assert.AreEqual(false, beatmapInfo.SpecialStyle); + Assert.IsTrue(beatmapInfo.RulesetID == 0); + Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks); + Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard); + } + } + + [Test] + public void TestDecodeEditor() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmap = decoder.Decode(new StreamReader(stream)).BeatmapInfo; + int[] expectedBookmarks = + { + 11505, 22054, 32604, 43153, 53703, 64252, 74802, 85351, + 95901, 106450, 116999, 119637, 130186, 140735, 151285, + 161834, 164471, 175020, 185570, 196119, 206669, 209306 + }; + Assert.AreEqual(expectedBookmarks.Length, beatmap.Bookmarks.Length); + for (int i = 0; i < expectedBookmarks.Length; i++) + Assert.AreEqual(expectedBookmarks[i], beatmap.Bookmarks[i]); + Assert.AreEqual(1.8, beatmap.DistanceSpacing); + Assert.AreEqual(4, beatmap.BeatDivisor); + Assert.AreEqual(4, beatmap.GridSize); + Assert.AreEqual(2, beatmap.TimelineZoom); + } + } + + [Test] + public void TestDecodeDifficulty() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmap = decoder.Decode(new StreamReader(stream)); + var difficulty = beatmap.BeatmapInfo.Difficulty; + Assert.AreEqual(6.5f, difficulty.DrainRate); + Assert.AreEqual(4, difficulty.CircleSize); + Assert.AreEqual(8, difficulty.OverallDifficulty); + Assert.AreEqual(9, difficulty.ApproachRate); + Assert.AreEqual(1.8f, difficulty.SliderMultiplier); + Assert.AreEqual(2, difficulty.SliderTickRate); + } + } + + [Test] + public void TestDecodeColors() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmap = decoder.Decode(new StreamReader(stream)); + Color4[] expected = + { + new Color4(142, 199, 255, 255), + new Color4(255, 128, 128, 255), + new Color4(128, 255, 255, 255), + new Color4(128, 255, 128, 255), + new Color4(255, 187, 255, 255), + new Color4(255, 177, 140, 255), + }; + Assert.AreEqual(expected.Length, beatmap.ComboColors.Count); + for (int i = 0; i < expected.Length; i++) + Assert.AreEqual(expected[i], beatmap.ComboColors[i]); + } + } + + [Test] + public void TestDecodeHitObjects() + { + var decoder = new OsuLegacyDecoder(); + using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + { + var beatmap = decoder.Decode(new StreamReader(stream)); + + var curveData = beatmap.HitObjects[0] as IHasCurve; + var positionData = beatmap.HitObjects[0] as IHasPosition; + + Assert.IsNotNull(positionData); + Assert.IsNotNull(curveData); + Assert.AreEqual(new Vector2(192, 168), positionData.Position); + Assert.AreEqual(956, beatmap.HitObjects[0].StartTime); + Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL)); + + positionData = beatmap.HitObjects[1] as IHasPosition; + + Assert.IsNotNull(positionData); + Assert.AreEqual(new Vector2(304, 56), positionData.Position); + Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime); + Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); + } + } + } +} \ No newline at end of file diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs new file mode 100644 index 0000000000..be48c997ea --- /dev/null +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -0,0 +1,164 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using osu.Framework.Platform; +using osu.Game.IPC; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; + +namespace osu.Game.Tests.Beatmaps.IO +{ + [TestFixture] + public class ImportBeatmapTest + { + private const string osz_path = @"../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz"; + + [Test] + public void TestImportWhenClosed() + { + //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. + using (HeadlessGameHost host = new HeadlessGameHost()) + { + var osu = loadOsu(host); + + var temp = prepareTempCopy(osz_path); + + Assert.IsTrue(File.Exists(temp)); + + osu.Dependencies.Get().Import(temp); + + ensureLoaded(osu); + + Assert.IsFalse(File.Exists(temp)); + } + } + + [Test] + public void TestImportOverIPC() + { + using (HeadlessGameHost host = new HeadlessGameHost("host", true)) + using (HeadlessGameHost client = new HeadlessGameHost("client", true)) + { + Assert.IsTrue(host.IsPrimaryInstance); + Assert.IsTrue(!client.IsPrimaryInstance); + + var osu = loadOsu(host); + + var temp = prepareTempCopy(osz_path); + + Assert.IsTrue(File.Exists(temp)); + + var importer = new BeatmapIPCChannel(client); + if (!importer.ImportAsync(temp).Wait(10000)) + Assert.Fail(@"IPC took too long to send"); + + ensureLoaded(osu); + + Assert.IsFalse(File.Exists(temp)); + } + } + + [Test] + public void TestImportWhenFileOpen() + { + //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. + using (HeadlessGameHost host = new HeadlessGameHost()) + { + var osu = loadOsu(host); + + var temp = prepareTempCopy(osz_path); + + Assert.IsTrue(File.Exists(temp), "Temporary file copy never substantiated"); + + using (File.OpenRead(temp)) + osu.Dependencies.Get().Import(temp); + + ensureLoaded(osu); + + File.Delete(temp); + + Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't"); + } + } + + private string prepareTempCopy(string path) + { + var temp = Path.GetTempFileName(); + return new FileInfo(path).CopyTo(temp, true).FullName; + } + + private OsuGameBase loadOsu(GameHost host) + { + host.Storage.DeleteDatabase(@"client"); + + var osu = new OsuGameBase(); + Task.Run(() => host.Run(osu)); + + while (!osu.IsLoaded) + Thread.Sleep(1); + + return osu; + } + + private void ensureLoaded(OsuGameBase osu, int timeout = 60000) + { + IEnumerable resultSets = null; + + var store = osu.Dependencies.Get(); + + Action waitAction = () => + { + while (!(resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any()) + Thread.Sleep(50); + }; + + Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), + @"BeatmapSet did not import to the database in allocated time."); + + //ensure we were stored to beatmap database backing... + + Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1)."); + + IEnumerable resultBeatmaps = null; + + //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. + waitAction = () => + { + while ((resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12) + Thread.Sleep(50); + }; + + Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), + @"Beatmaps did not import to the database in allocated time"); + + var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First(); + + Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(), + $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count})."); + + foreach (BeatmapInfo b in resultBeatmaps) + Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); + + Assert.IsTrue(set.Beatmaps.Count > 0); + + var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap; + Assert.IsTrue(beatmap?.HitObjects.Count > 0); + + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap; + Assert.IsTrue(beatmap?.HitObjects.Count > 0); + + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap; + Assert.IsTrue(beatmap?.HitObjects.Count > 0); + + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; + Assert.IsTrue(beatmap?.HitObjects.Count > 0); + } + } +} diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs new file mode 100644 index 0000000000..7a7a8a58bc --- /dev/null +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.IO; +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.IO; +using osu.Game.Tests.Resources; +using osu.Game.Beatmaps.Formats; + +namespace osu.Game.Tests.Beatmaps.IO +{ + [TestFixture] + public class OszArchiveReaderTest + { + [Test] + public void TestReadBeatmaps() + { + using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz")) + { + var reader = new OszArchiveReader(osz); + string[] expected = + { + "Soleily - Renatus (Deif) [Platter].osu", + "Soleily - Renatus (Deif) [Rain].osu", + "Soleily - Renatus (Deif) [Salad].osu", + "Soleily - Renatus (ExPew) [Another].osu", + "Soleily - Renatus (ExPew) [Hyper].osu", + "Soleily - Renatus (ExPew) [Normal].osu", + "Soleily - Renatus (Gamu) [Hard].osu", + "Soleily - Renatus (Gamu) [Insane].osu", + "Soleily - Renatus (Gamu) [Normal].osu", + "Soleily - Renatus (MMzz) [Futsuu].osu", + "Soleily - Renatus (MMzz) [Muzukashii].osu", + "Soleily - Renatus (MMzz) [Oni].osu" + }; + var maps = reader.Filenames.ToArray(); + foreach (var map in expected) + Assert.Contains(map, maps); + } + } + + [Test] + public void TestReadMetadata() + { + using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz")) + { + var reader = new OszArchiveReader(osz); + + BeatmapMetadata meta; + using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) + meta = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata; + + Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + Assert.AreEqual("Soleily", meta.Artist); + Assert.AreEqual("Soleily", meta.ArtistUnicode); + Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); + Assert.AreEqual("Deif", meta.Author); + Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile); + Assert.AreEqual(164471, meta.PreviewTime); + Assert.AreEqual(string.Empty, meta.Source); + Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags); + Assert.AreEqual("Renatus", meta.Title); + Assert.AreEqual("Renatus", meta.TitleUnicode); + } + } + + [Test] + public void TestReadFile() + { + using (var osz = Resource.OpenResource("Beatmaps.241526 Soleily - Renatus.osz")) + { + var reader = new OszArchiveReader(osz); + using (var stream = new StreamReader( + reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) + { + Assert.AreEqual("osu file format v13", stream.ReadLine()?.Trim()); + } + } + } + } +} diff --git a/osu.Game.Tests/OpenTK.dll.config b/osu.Game.Tests/OpenTK.dll.config new file mode 100644 index 0000000000..5620e3d9e2 --- /dev/null +++ b/osu.Game.Tests/OpenTK.dll.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/osu.Game.Tests/Resources/Resource.cs b/osu.Game.Tests/Resources/Resource.cs new file mode 100644 index 0000000000..6c66b6818b --- /dev/null +++ b/osu.Game.Tests/Resources/Resource.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.IO; +using System.Reflection; + +namespace osu.Game.Tests.Resources +{ + public static class Resource + { + public static Stream OpenResource(string name) + { + var localPath = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); + + return Assembly.GetExecutingAssembly().GetManifestResourceStream($@"osu.Game.Tests.Resources.{name}") ?? + Assembly.LoadFrom(Path.Combine(localPath, @"osu.Game.Resources.dll")).GetManifestResourceStream($@"osu.Game.Resources.{name}"); + } + } +} \ No newline at end of file diff --git a/osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu b/osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu new file mode 100644 index 0000000000..3e44dc0af8 --- /dev/null +++ b/osu.Game.Tests/Resources/Soleily - Renatus (Gamu) [Insane].osu @@ -0,0 +1,1002 @@ +osu file format v14 + +[General] +AudioFilename: 03. Renatus - Soleily 192kbps.mp3 +AudioLeadIn: 0 +PreviewTime: 164471 +Countdown: 0 +SampleSet: Soft +StackLeniency: 0.7 +Mode: 0 +LetterboxInBreaks: 0 +WidescreenStoryboard: 0 + +[Editor] +Bookmarks: 11505,22054,32604,43153,53703,64252,74802,85351,95901,106450,116999,119637,130186,140735,151285,161834,164471,175020,185570,196119,206669,209306 +DistanceSpacing: 1.8 +BeatDivisor: 4 +GridSize: 4 +TimelineZoom: 2 + +[Metadata] +Title:Renatus +TitleUnicode:Renatus +Artist:Soleily +ArtistUnicode:Soleily +Creator:Gamu +Version:Insane +Source: +Tags:MBC7 Unisphere 地球ヤバイEP Chikyu Yabai +BeatmapID:557821 +BeatmapSetID:241526 + +[Difficulty] +HPDrainRate:6.5 +CircleSize:4 +OverallDifficulty:8 +ApproachRate:9 +SliderMultiplier:1.8 +SliderTickRate:2 + +[Events] +//Background and Video events +0,0,"machinetop_background.jpg",0,0 +//Break Periods +2,122474,140135 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples + +[TimingPoints] +956,329.67032967033,4,2,0,60,1,0 +20736,-100,4,2,0,65,0,0 +22054,-100,4,2,0,70,0,0 +43153,-100,4,2,0,60,0,0 +48428,-100,4,2,0,50,0,0 +52879,-100,4,2,0,50,0,0 +53373,-100,4,2,0,60,0,0 +53703,-100,4,2,0,70,0,1 +74719,-100,4,2,0,70,0,0 +74802,-100,4,2,0,70,0,1 +95901,-100,4,2,0,70,0,0 +116999,-133.333333333333,4,2,0,50,0,0 +117164,-133.333333333333,4,2,0,30,0,0 +117329,-79.9999999999999,4,2,0,50,0,0 +117659,-100,4,2,0,50,0,0 +118977,-100,4,2,0,60,0,0 +119307,-100,4,2,0,70,0,0 +119637,659.340659340659,4,2,0,80,1,0 +119966,-100,4,2,0,70,0,0 +120296,-100,4,2,0,60,0,0 +120626,-100,4,2,0,50,0,0 +120955,-100,4,2,0,40,0,0 +121285,-100,4,2,0,30,0,0 +121615,-100,4,2,0,20,0,0 +121944,-100,4,2,0,10,0,0 +122274,-100,4,2,0,5,0,0 +140735,-100,4,2,0,50,0,0 +151285,-80,4,2,0,60,0,0 +161834,329.67032967033,4,2,0,65,1,0 +164141,-100,4,2,0,70,0,0 +164471,-100,4,2,0,70,0,1 +185487,-100,4,2,0,70,0,0 +185570,-100,4,2,0,70,0,1 +206669,659.340659340659,4,2,0,80,1,0 +206998,-100,4,2,0,70,0,0 +207328,-100,4,2,0,60,0,0 +207658,-100,4,2,0,50,0,0 +207987,-100,4,2,0,40,0,0 +208317,-100,4,2,0,30,0,0 +208647,-100,4,2,0,20,0,0 +208976,-100,4,2,0,10,0,0 +209306,-100,4,2,0,5,0,0 + + +[Colours] +Combo1 : 142,199,255 +Combo2 : 255,128,128 +Combo3 : 128,255,255 +Combo4 : 128,255,128 +Combo5 : 255,187,255 +Combo6 : 255,177,140 + +[HitObjects] +192,168,956,6,0,P|184:128|200:80,1,90,4|0,1:2|0:0,0:0:0:0: +304,56,1285,1,8,0:0:0:0: +244,236,1450,2,0,P|204:252|156:244,1,90,2|0,0:0|0:0,0:0:0:0: +276,156,1780,2,0,P|310:181|329:226,1,90,2|8,1:2|0:0,0:0:0:0: +300,328,2109,1,2,0:0:0:0: +192,332,2274,6,0,L|144:340,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +388,300,2604,1,8,0:0:0:0: +244,236,2769,1,0,1:0:0:0: +232,208,2851,1,0,0:0:0:0: +224,176,2934,1,0,0:0:0:0: +228,144,3016,1,0,0:0:0:0: +244,116,3098,1,0,1:0:0:0: +332,52,3263,2,0,P|376:48|424:56,1,90,8|0,0:0|0:0,0:0:0:0: +488,228,3593,5,0,1:0:0:0: +460,240,3675,1,0,0:0:0:0: +428,236,3758,1,0,0:0:0:0: +292,160,3923,2,0,P|288:204|300:252,1,90,8|0,0:0|0:0,0:0:0:0: +316,276,4170,1,0,0:0:0:0: +344,292,4252,2,0,L|388:300,1,45,0|0,0:0|0:0,0:0:0:0: +288,356,4417,2,0,L|244:364,1,45,0|0,1:0|0:0,0:0:0:0: +168,328,4582,2,0,P|124:324|72:332,1,90,8|0,0:0|0:0,0:0:0:0: +24,188,4912,5,0,1:0:0:0: +56,192,4994,1,0,0:0:0:0: +88,196,5076,1,0,0:0:0:0: +148,108,5241,1,8,0:0:0:0: +188,240,5406,1,0,1:0:0:0: +188,240,5488,1,0,0:0:0:0: +188,240,5571,2,0,L|168:328,1,90,0|0,0:0|1:0,0:0:0:0: +260,216,5901,2,0,P|236:180|188:164,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,6230,6,0,L|348:292,1,90,0|0,1:0|0:0,0:0:0:0: +504,232,6560,1,8,0:0:0:0: +400,204,6725,1,0,0:0:0:0: +392,176,6807,1,0,0:0:0:0: +384,144,6890,1,0,0:0:0:0: +376,116,6972,1,0,0:0:0:0: +368,88,7054,1,0,1:0:0:0: +188,48,7219,2,0,L|208:140,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,7549,5,0,1:0:0:0: +207,135,7714,1,0,0:0:0:0: +156,232,7879,1,8,0:0:0:0: +316,191,8043,1,0,1:0:0:0: +316,191,8126,1,0,0:0:0:0: +316,191,8208,2,0,L|372:200,1,45,0|0,0:0|0:0,0:0:0:0: +492,200,8373,2,0,L|447:207,1,45,0|0,1:0|0:0,0:0:0:0: +408,136,8538,2,0,P|396:92|400:48,1,90,8|0,0:0|0:0,0:0:0:0: +260,32,8868,5,0,1:0:0:0: +252,64,8950,1,0,0:0:0:0: +236,92,9032,2,0,P|204:116|148:128,1,90,0|8,0:0|0:0,0:0:0:0: +28,188,9362,1,0,0:0:0:0: +60,196,9445,1,0,0:0:0:0: +88,212,9527,2,0,P|112:244|124:300,1,90,0|0,0:0|1:0,0:0:0:0: +112,128,9857,2,0,P|152:156|184:196,1,90,8|0,0:0|0:0,0:0:0:0: +216,288,10186,5,0,1:0:0:0: +216,288,10269,1,0,0:0:0:0: +216,288,10351,1,0,0:0:0:0: +268,192,10516,1,8,0:0:0:0: +356,128,10681,1,0,1:0:0:0: +388,120,10763,1,0,0:0:0:0: +420,128,10846,2,0,P|440:168|436:220,1,90,0|0,0:0|1:0,0:0:0:0: +332,328,11175,2,0,L|280:332,1,45,8|8,0:0|0:0,0:0:0:0: +216,288,11340,2,0,L|164:292,1,45,0|0,1:0|0:0,1:0:0:0: +100,248,11505,5,4,1:2:0:0: +148,116,11670,1,2,0:0:0:0: +268,192,11835,1,10,0:0:0:0: +136,328,11999,2,0,L|44:336,1,90,2|0,0:0|0:0,0:0:0:0: +216,288,12329,1,2,1:2:0:0: +148,116,12494,1,10,0:0:0:0: +100,248,12659,1,2,0:0:0:0: +268,192,12824,5,0,1:0:0:0: +268,192,12906,1,0,0:0:0:0: +268,192,12988,1,0,0:0:0:0: +340,272,13153,2,0,P|384:276|432:264,1,90,8|0,0:0|1:0,0:0:0:0: +452,244,13401,1,0,0:0:0:0: +468,216,13483,2,0,L|476:124,1,90,0|0,0:0|1:0,0:0:0:0: +368,32,13813,2,0,L|360:121,1,90,8|0,0:0|0:0,0:0:0:0: +340,272,14142,6,0,L|316:316,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +452,244,14472,1,8,0:0:0:0: +268,192,14637,1,0,0:0:0:0: +236,188,14719,1,0,0:0:0:0: +204,192,14802,2,0,P|172:228|160:272,1,90,0|0,0:0|1:0,0:0:0:0: +128,140,15131,2,0,P|160:104|172:60,1,90,8|0,0:0|0:0,0:0:0:0: +64,52,15461,6,0,L|20:68,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +171,64,15791,1,8,0:0:0:0: +264,8,15956,2,0,L|356:12,1,90,0|0,1:0|0:0,0:0:0:0: +452,56,16285,1,0,1:0:0:0: +296,140,16450,2,0,L|206:136,1,90,8|0,0:0|0:0,0:0:0:0: +108,184,16780,6,0,P|92:224|96:272,1,90,0|0,1:0|0:0,0:0:0:0: +200,244,17109,1,8,0:0:0:0: +108,108,17274,2,0,L|12:116,1,90,0|0,0:0|0:0,0:0:0:0: +200,244,17604,1,0,1:0:0:0: +296,140,17769,2,0,L|385:132,1,90,8|0,0:0|0:0,0:0:0:0: +480,184,18098,5,0,1:0:0:0: +488,216,18181,1,0,0:0:0:0: +496,248,18263,2,0,L|492:340,1,90,0|8,0:0|0:0,0:0:0:0: +404,224,18593,2,0,L|396:176,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +304,264,18923,1,0,1:0:0:0: +200,244,19087,2,0,P|156:240|108:248,1,90,8|0,0:0|0:0,0:0:0:0: +296,140,19417,6,0,P|340:144|388:136,1,90,0|0,1:0|0:0,0:0:0:0: +440,44,19747,1,8,0:0:0:0: +404,224,19912,1,0,0:0:0:0: +404,224,19994,1,0,0:0:0:0: +404,224,20076,2,0,L|412:320,1,90,0|0,0:0|1:0,0:0:0:0: +200,244,20406,2,0,L|192:154,1,90,8|0,0:0|0:0,0:0:0:0: +184,44,20736,5,4,1:2:0:0: +152,40,20818,1,0,0:0:0:0: +120,48,20901,1,0,0:0:0:0: +96,68,20983,1,0,0:0:0:0: +76,92,21065,1,2,0:3:0:0: +64,120,21148,1,0,0:0:0:0: +60,152,21230,1,0,1:0:0:0: +64,184,21313,1,0,0:0:0:0: +76,212,21395,2,0,L|96:252,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +144,316,21725,2,0,L|188:324,3,45,0|0|2|0,0:0|0:0|0:3|0:0,0:0:0:0: +268,340,22054,6,0,L|364:336,1,90,4|0,1:2|0:0,0:0:0:0: +452,280,22384,1,8,0:0:0:0: +512,188,22549,2,0,P|516:144|504:96,1,90,2|0,0:0|0:0,0:0:0:0: +340,24,22879,2,0,P|336:68|348:116,1,90,2|8,1:2|0:0,0:0:0:0: +420,192,23208,1,2,0:0:0:0: +328,252,23373,6,0,L|232:240,1,90,0|0,1:0|0:0,0:0:0:0: +64,256,23703,1,8,0:0:0:0: +144,184,23868,2,0,P|148:140|136:88,1,90,0|0,1:0|0:0,0:0:0:0: +40,52,24197,1,2,1:2:0:0: +139,95,24362,1,8,0:0:0:0: +216,20,24527,1,0,0:0:0:0: +315,63,24692,6,0,P|360:72|408:68,1,90,2|0,1:2|0:0,0:0:0:0: +492,132,25021,1,8,0:0:0:0: +412,204,25186,2,0,P|403:249|407:297,1,90,2|0,0:0|0:0,0:0:0:0: +268,328,25516,2,0,P|277:283|273:235,1,90,2|8,1:2|0:0,0:0:0:0: +232,140,25846,2,0,P|187:131|139:135,1,90,2|0,0:0|1:0,0:0:0:0: +64,208,26175,5,2,0:0:0:0: +44,316,26340,1,8,0:0:0:0: +148,280,26505,1,2,1:2:0:0: +456,208,26835,1,2,1:2:0:0: +476,316,26999,1,10,0:0:0:0: +372,280,27164,1,2,0:0:0:0: +356,172,27329,6,0,L|380:80,1,90,0|0,1:0|0:0,0:0:0:0: +456,208,27659,1,8,0:0:0:0: +300,236,27824,1,2,0:0:0:0: +300,236,27906,1,0,0:0:0:0: +300,236,27988,2,0,L|208:228,1,90,0|2,0:0|1:2,0:0:0:0: +140,312,28318,1,8,0:0:0:0: +372,280,28483,2,0,L|464:272,1,90,2|0,0:0|1:0,0:0:0:0: +500,136,28813,5,2,0:0:0:0: +432,56,28977,1,8,0:0:0:0: +328,24,29142,2,0,P|284:24|236:28,1,90,2|0,1:2|0:0,0:0:0:0: +80,144,29472,1,2,1:2:0:0: +116,44,29637,1,10,0:0:0:0: +184,128,29802,1,2,0:0:0:0: +20,88,29966,6,0,P|1:164|73:227,1,180,2|10,1:2|0:0,0:0:0:0: +184,128,30461,2,0,P|227:120|276:124,1,90,2|0,0:0|0:0,0:0:0:0: +392,188,30791,1,2,1:2:0:0: +272,260,30956,1,8,0:0:0:0: +396,328,31120,1,0,0:0:0:0: +256,348,31285,5,2,1:2:0:0: +224,344,31368,1,0,1:0:0:0: +192,340,31450,2,0,L|172:248,1,90,2|0,1:2|1:0,0:0:0:0: +8,136,31780,2,0,L|27:223,1,90,2|0,1:2|0:0,0:0:0:0: +56,328,32109,1,2,1:2:0:0: +108,192,32274,1,2,1:2:0:0: +100,160,32357,1,0,1:0:0:0: +92,132,32439,1,2,1:2:0:0: +84,104,32521,1,0,1:0:0:0: +76,72,32604,6,0,P|100:112|148:136,1,90,4|0,1:2|0:0,0:0:0:0: +240,168,32934,1,8,0:0:0:0: +336,124,33098,2,0,L|344:80,2,45,2|0|0,0:0|0:0|0:0,0:0:0:0: +264,248,33428,2,0,P|220:248|176:220,1,90,2|8,1:2|0:0,0:0:0:0: +260,84,33758,1,2,0:0:0:0: +344,212,33923,5,0,1:0:0:0: +344,212,34005,1,0,0:0:0:0: +344,212,34087,1,0,0:0:0:0: +440,160,34252,1,8,0:0:0:0: +312,320,34417,2,0,P|272:336|220:324,1,90,0|0,1:0|0:0,0:0:0:0: +156,176,34747,2,0,P|196:160|248:172,2,90,2|8|0,1:2|0:0|0:0,0:0:0:0: +132,280,35241,5,2,1:2:0:0: +132,280,35324,1,0,0:0:0:0: +132,280,35406,2,0,L|120:376,1,90,0|8,0:0|0:0,0:0:0:0: +312,320,35736,2,0,L|300:230,1,90,2|0,0:0|0:0,0:0:0:0: +316,124,36065,1,2,1:2:0:0: +400,192,36230,1,8,0:0:0:0: +300,230,36395,2,0,P|255:231|211:224,1,90,2|0,0:0|1:0,0:0:0:0: +24,132,36725,5,0,0:0:0:0: +132,152,36890,1,8,0:0:0:0: +60,232,37054,1,2,1:2:0:0: +60,232,37137,1,0,0:0:0:0: +60,232,37219,1,0,0:0:0:0: +92,56,37384,2,0,L|184:44,1,90,2|10,1:2|0:0,0:0:0:0: +316,124,37714,2,0,L|226:135,1,90,2|0,0:0|1:0,0:0:0:0: +60,232,38043,6,0,P|52:276|64:328,1,90,0|8,0:0|0:0,0:0:0:0: +220,152,38373,2,0,P|176:144|124:156,1,90,2|0,0:0|0:0,0:0:0:0: +176,252,38703,1,2,1:2:0:0: +323,213,38868,2,0,L|316:124,1,90,8|2,0:0|0:0,0:0:0:0: +332,320,39197,5,0,1:0:0:0: +424,260,39362,1,2,0:0:0:0: +260,272,39527,2,0,P|246:313|256:360,1,90,8|2,0:0|1:2,0:0:0:0: +408,336,39857,1,0,0:0:0:0: +176,252,40021,2,0,L|80:260,2,90,2|10|2,1:2|0:0|0:0,0:0:0:0: +324,212,40516,5,2,1:2:0:0: +324,212,40598,1,0,1:0:0:0: +324,212,40681,1,0,1:0:0:0: +200,336,40846,1,2,1:2:0:0: +236,188,41010,1,2,1:2:0:0: +236,188,41093,1,0,1:0:0:0: +236,188,41175,1,0,1:0:0:0: +281,357,41340,1,2,1:2:0:0: +176,252,41505,1,2,1:2:0:0: +176,252,41587,1,0,1:0:0:0: +176,252,41670,1,0,1:0:0:0: +344,297,41835,5,2,1:2:0:0: +432,232,41999,1,2,1:2:0:0: +444,204,42082,1,0,1:0:0:0: +448,172,42164,1,0,1:0:0:0: +444,140,42247,1,0,1:0:0:0: +432,112,42329,2,0,L|440:64,2,45,2|0|0,1:2|1:0|1:0,0:0:0:0: +236,188,42659,1,0,0:0:0:0: +340,172,42824,1,2,0:3:0:0: +272,88,42988,1,0,0:0:0:0: +132,160,43153,6,0,P|148:248|220:296,1,180,4|8,1:2|0:0,0:0:0:0: +324,320,43648,2,0,L|336:364,2,45,0|0|0,0:0|0:0|0:0,0:0:0:0: +292,216,43977,1,0,1:0:0:0: +396,240,44142,2,0,P|440:244|488:232,1,90,8|0,0:0|0:0,0:0:0:0: +328,124,44472,6,0,P|284:120|236:132,1,90,0|0,1:0|0:0,0:0:0:0: +168,212,44802,1,8,0:0:0:0: +192,316,44966,1,0,1:0:0:0: +140,220,45131,1,0,0:0:0:0: +83,310,45296,1,0,1:0:0:0: +114,205,45461,1,8,0:0:0:0: +10,229,45626,1,0,0:0:0:0: +106,176,45791,6,0,P|113:133|108:85,1,90,0|0,1:0|0:0,0:0:0:0: +204,136,46120,1,8,0:0:0:0: +256,40,46285,1,0,0:0:0:0: +256,40,46368,1,0,0:0:0:0: +256,40,46450,2,0,L|356:44,1,90,0|0,0:0|1:0,0:0:0:0: +501,124,46780,2,0,L|412:128,1,90,8|0,0:0|0:0,0:0:0:0: +324,192,47109,5,0,1:0:0:0: +356,296,47274,1,0,0:0:0:0: +284,216,47439,1,8,0:0:0:0: +269,323,47604,1,0,1:0:0:0: +237,220,47769,1,0,0:0:0:0: +178,311,47934,1,0,1:0:0:0: +191,203,48098,1,8,0:0:0:0: +99,261,48263,1,0,0:0:0:0: +156,168,48428,6,0,B|176:112|136:64|136:64|200:96,1,180,4|8,1:2|0:0,0:0:0:0: +300,124,48923,2,0,L|392:120,1,90,0|0,0:0|0:0,0:0:0:0: +468,48,49252,1,0,1:0:0:0: +390,120,49417,2,0,P|390:164|406:208,1,90,8|0,0:0|0:0,0:0:0:0: +352,344,49747,6,0,P|352:300|336:256,1,90,4|0,1:2|0:0,0:0:0:0: +240,208,50076,1,8,0:0:0:0: +163,320,50241,2,0,P|207:324|252:316,1,90,0|0,1:0|0:0,0:0:0:0: +240,208,50571,1,0,1:0:0:0: +76,296,50736,2,0,P|76:340|92:384,1,90,8|0,0:0|0:0,0:0:0:0: +312,164,51065,6,0,P|236:124|160:184,1,180,4|8,1:2|0:0,0:0:0:0: +247,297,51560,2,0,L|240:208,1,90,0|0,0:0|0:0,0:0:0:0: +224,48,51890,1,0,1:0:0:0: +332,56,52054,2,0,L|366:58,5,30,8|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0: +408,64,52384,6,0,P|420:108|416:156,1,90,0|0,1:0|0:0,0:0:0:0: +360,260,52714,1,8,0:0:0:0: +247,297,52879,2,0,B|203:281|159:297|159:297|115:313|71:297,1,180,0|0,1:0|1:0,0:0:0:0: +116,196,53373,1,8,0:0:0:0: +120,164,53456,1,0,0:0:0:0: +124,132,53538,1,0,0:0:0:0: +128,100,53620,1,0,0:0:0:0: +132,68,53703,5,4,1:2:0:0: +40,136,53868,1,0,0:0:0:0: +204,160,54032,2,0,L|304:152,1,90,8|0,0:0|0:0,0:0:0:0: +408,64,54362,1,0,0:0:0:0: +408,64,54445,1,0,0:0:0:0: +408,64,54527,2,0,P|404:112|416:160,1,90,0|8,1:0|0:0,0:0:0:0: +484,236,54857,1,0,0:0:0:0: +428,328,55021,5,0,1:0:0:0: +328,296,55186,1,0,0:0:0:0: +328,296,55269,1,0,0:0:0:0: +328,296,55351,1,8,0:0:0:0: +416,300,55516,1,0,1:0:0:0: +472,208,55681,1,0,0:0:0:0: +316,268,55846,1,0,1:0:0:0: +460,180,56010,1,8,0:0:0:0: +304,240,56175,1,0,0:0:0:0: +404,272,56340,5,0,1:0:0:0: +448,152,56505,1,0,0:0:0:0: +448,152,56587,1,0,0:0:0:0: +448,152,56670,2,0,P|456:112|448:60,1,90,8|0,0:0|0:0,0:0:0:0: +268,28,56999,2,0,P|260:68|268:120,1,90,0|0,0:0|1:0,0:0:0:0: +404,272,57329,2,0,P|444:280|496:272,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +304,240,57824,5,0,0:0:0:0: +252,336,57988,1,8,0:0:0:0: +196,244,58153,1,0,1:0:0:0: +24,256,58318,1,0,0:0:0:0: +116,200,58483,1,0,1:0:0:0: +136,60,58648,1,8,0:0:0:0: +192,152,58813,1,0,0:0:0:0: +304,240,58977,6,0,P|348:252|396:248,1,90,0|0,1:0|0:0,0:0:0:0: +456,116,59307,2,0,P|412:104|364:108,1,90,8|0,0:0|0:0,0:0:0:0: +273,161,59637,1,0,0:0:0:0: +136,60,59802,1,0,1:0:0:0: +192,152,59966,1,8,0:0:0:0: +23,177,60131,1,0,0:0:0:0: +129,203,60296,5,0,1:0:0:0: +88,304,60461,2,0,P|132:311|176:303,1,90,0|8,0:0|0:0,0:0:0:0: +304,240,60791,1,0,1:0:0:0: +304,240,60873,1,0,0:0:0:0: +304,240,60956,2,0,L|312:288,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +384,256,61285,2,0,L|392:304,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +464,272,61615,5,2,1:2:0:0: +488,168,61780,1,2,0:0:0:0: +428,80,61945,1,10,0:0:0:0: +332,32,62109,2,0,P|288:28|240:36,1,90,2|0,0:0|0:0,0:0:0:0: +28,216,62439,1,2,1:2:0:0: +88,304,62604,1,10,0:0:0:0: +184,352,62769,2,0,P|228:356|276:348,1,90,2|0,0:0|1:0,0:0:0:0: +384,256,63098,6,0,P|409:219|426:174,1,90,2|8,0:0|0:0,0:0:0:0: +428,80,63428,2,0,L|420:36,2,45,2|0|0,1:2|0:0|0:0,0:0:0:0: +456,288,63758,1,2,1:2:0:0: +324,200,63923,1,10,1:2:0:0: +292,204,64005,1,0,1:0:0:0: +260,208,64087,1,2,1:2:0:0: +228,212,64170,1,0,1:0:0:0: +196,216,64252,5,4,1:2:0:0: +104,160,64417,1,0,0:0:0:0: +228,296,64582,2,0,L|320:284,1,90,8|0,0:0|0:0,0:0:0:0: +344,112,64912,1,0,0:0:0:0: +344,112,64994,1,0,0:0:0:0: +344,112,65076,2,0,L|254:123,1,90,0|8,1:0|0:0,0:0:0:0: +144,284,65406,2,0,P|148:328|176:364,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,65736,5,0,0:0:0:0: +196,216,65818,1,0,0:0:0:0: +196,216,65901,2,0,P|155:198|110:205,1,90,8|0,0:0|1:0,0:0:0:0: +36,284,66230,1,0,0:0:0:0: +4,180,66395,1,0,1:0:0:0: +132,24,66560,1,8,0:0:0:0: +100,128,66725,1,0,0:0:0:0: +24,48,66890,5,0,1:0:0:0: +212,108,67054,1,0,0:0:0:0: +212,108,67137,1,0,0:0:0:0: +212,108,67219,2,0,L|300:92,1,90,8|0,0:0|0:0,0:0:0:0: +472,144,67549,2,0,L|384:160,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,67879,2,0,P|240:216|288:240,1,90,8|0,0:0|0:0,0:0:0:0: +324,336,68208,5,0,1:0:0:0: +144,288,68373,1,0,0:0:0:0: +58,170,68538,1,8,0:0:0:0: +196,215,68703,1,0,1:0:0:0: +58,260,68868,1,0,0:0:0:0: +144,142,69032,2,0,L|138:108,2,30,0|0|0,1:0|0:0|0:0,0:0:0:0: +144,142,69197,2,0,P|184:124|232:132,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,69527,6,0,L|324:338,1,90,0|0,1:0|0:0,0:0:0:0: +436,248,69857,1,8,0:0:0:0: +432,216,69939,1,0,0:0:0:0: +428,184,70021,1,0,0:0:0:0: +328,120,70186,1,0,0:0:0:0: +324,152,70269,1,0,0:0:0:0: +320,184,70351,1,0,1:0:0:0: +316,216,70434,1,0,0:0:0:0: +312,248,70516,2,0,L|320:300,1,45,8|0,0:0|0:0,0:0:0:0: +244,340,70681,2,0,L|237:295,1,45,0|0,0:0|0:0,0:0:0:0: +216,224,70846,6,0,P|168:216|124:224,1,90,0|0,1:0|0:0,0:0:0:0: +40,288,71175,1,8,0:0:0:0: +2,95,71340,2,0,P|-4:139|4:184,1,90,0|0,1:0|0:0,0:0:0:0: +164,304,71670,1,0,1:0:0:0: +312,248,71835,1,8,0:0:0:0: +244,340,71999,1,0,0:0:0:0: +216,224,72164,6,0,L|228:132,1,90,0|0,1:0|0:0,0:0:0:0: +332,148,72494,2,0,L|344:56,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,72824,1,0,0:0:0:0: +164,304,72988,1,0,1:0:0:0: +332,336,73153,1,8,0:0:0:0: +360,324,73236,1,0,0:0:0:0: +384,304,73318,1,0,0:0:0:0: +399,276,73401,1,0,0:0:0:0: +403,244,73483,6,0,L|396:200,3,45,4|0|2|0,1:2|0:0|0:0|1:0,0:0:0:0: +420,112,73813,2,0,L|427:68,3,45,2|0|2|0,1:2|0:0|1:2|0:0,0:0:0:0: +352,16,74142,2,0,L|345:60,3,45,0|0|2|0,0:0|1:0|1:2|0:0,0:0:0:0: +332,148,74472,1,2,1:2:0:0: +332,148,74554,1,0,1:0:0:0: +332,148,74637,1,2,1:2:0:0: +332,148,74719,1,0,1:0:0:0: +332,148,74802,6,0,P|360:216|320:312,1,180,4|2,1:2|0:3,0:0:0:0: +190,310,75296,2,0,P|151:231|180:148,1,180,4|0,1:2|0:0,0:0:0:0: +256,56,75791,1,0,0:0:0:0: +332,148,75956,1,2,0:3:0:0: +179,148,76120,5,4,1:2:0:0: +336,64,76285,1,4,1:2:0:0: +256,224,76450,1,2,0:3:0:0: +176,64,76615,1,4,1:2:0:0: +256,140,76780,2,0,L|256:324,1,180,2|0,0:0|0:0,0:0:0:0: +364,300,77274,1,2,0:3:0:0: +148,300,77439,6,0,P|104:316|76:356,1,90,4|0,1:2|0:0,0:0:0:0: +24,252,77769,2,0,L|16:208,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +96,212,78098,2,0,L|104:168,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +32,128,78428,2,0,L|24:84,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +104,88,78758,5,2,1:2:0:0: +204,132,78923,1,0,0:0:0:0: +236,124,79005,1,0,0:0:0:0: +268,116,79087,2,0,L|280:68,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +348,100,79417,2,0,L|360:52,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +428,84,79747,1,8,1:2:0:0: +460,76,79829,1,0,1:0:0:0: +492,68,79912,1,0,1:0:0:0: +492,260,80076,6,0,P|400:248|328:296,1,180,4|2,1:2|0:3,0:0:0:0: +144,236,80571,2,0,P|236:248|308:200,1,180,4|0,1:2|0:0,0:0:0:0: +348,100,81065,2,0,P|348:56|336:8,1,90,0|2,0:0|0:3,0:0:0:0: +140,48,81395,5,4,1:2:0:0: +244,68,81560,1,4,1:2:0:0: +144,236,81725,1,2,0:3:0:0: +176,133,81890,1,4,1:2:0:0: +184,304,82054,2,0,P|100:300|68:220,1,180,2|0,0:0|0:0,0:0:0:0: +100,116,82549,1,2,0:3:0:0: +264,244,82714,6,0,L|272:340,1,90,4|0,1:2|0:0,0:0:0:0: +380,316,83043,1,8,0:0:0:0: +396,288,83126,1,0,0:0:0:0: +400,256,83208,1,0,0:0:0:0: +396,224,83291,1,0,0:0:0:0: +380,196,83373,2,0,L|336:176,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +272,148,83703,1,8,0:0:0:0: +256,120,83785,1,0,0:0:0:0: +252,88,83868,1,0,0:0:0:0: +256,56,83950,1,0,0:0:0:0: +272,28,84032,6,0,L|316:8,3,45,2|0|0|0,1:2|0:0|0:0|0:0,0:0:0:0: +360,72,84362,2,0,L|408:72,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +421,149,84692,2,0,L|464:169,3,45,2|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +443,244,85021,2,0,L|473:281,3,45,8|0|0|0,1:2|1:0|0:0|0:0,0:0:0:0: +422,339,85351,6,0,L|240:348,1,180,4|2,1:2|0:3,0:0:0:0: +76,172,85846,2,0,L|255:163,1,180,4|0,1:2|0:0,0:0:0:0: +421,149,86340,2,0,P|435:107|428:56,1,90,0|2,0:0|0:3,0:0:0:0: +228,56,86670,5,4,1:2:0:0: +280,192,86835,1,4,1:2:0:0: +328,96,86999,1,2,0:3:0:0: +180,152,87164,1,4,1:2:0:0: +28,100,87330,2,0,P|16:56|20:8,1,90,2|0,0:0|0:0,0:0:0:0: +0,180,87659,1,0,0:0:0:0: +28,284,87824,1,2,0:3:0:0: +108,352,87988,6,0,P|152:360|196:356,1,90,4|0,1:2|0:0,0:0:0:0: +276,284,88318,1,8,0:0:0:0: +304,272,88401,1,0,0:0:0:0: +336,268,88483,1,0,0:0:0:0: +368,272,88565,1,0,0:0:0:0: +396,284,88648,2,0,L|432:312,1,45,0|0,0:0|0:0,0:0:0:0: +488,252,88813,2,0,L|452:224,1,45,0|0,1:0|0:0,0:0:0:0: +400,164,88977,2,0,L|396:116,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +316,64,89307,6,0,L|320:160,1,90,2|0,1:2|0:0,0:0:0:0: +276,284,89637,1,8,0:0:0:0: +248,296,89719,1,0,0:0:0:0: +216,300,89802,1,0,1:0:0:0: +184,296,89884,1,0,0:0:0:0: +156,284,89966,2,0,L|120:256,1,45,0|0,0:0|0:0,0:0:0:0: +176,200,90131,2,0,L|140:172,1,45,0|0,1:0|0:0,0:0:0:0: +196,116,90296,2,0,L|160:88,3,45,8|0|0|0,1:2|1:0|1:0|0:0,0:0:0:0: +92,44,90626,6,0,P|48:44|24:160,1,180,4|2,1:2|0:3,0:0:0:0: +156,284,91120,2,0,B|200:300|244:284|244:284|288:268|332:284,1,180,4|0,1:2|0:0,0:0:0:0: +176,200,91615,2,0,P|176:156|196:116,1,90,0|2,0:0|0:3,0:0:0:0: +264,28,91945,6,0,L|353:39,1,90,4|0,1:2|1:0,0:0:0:0: +453,159,92274,2,0,L|364:148,1,90,2|4,0:3|1:2,0:0:0:0: +268,196,92604,2,0,P|260:268|328:348,1,180,2|0,0:0|0:0,0:0:0:0: +364,248,93098,1,2,0:3:0:0: +176,200,93263,5,4,1:2:0:0: +72,228,93428,1,0,1:0:0:0: +152,92,93593,1,0,1:0:0:0: +256,64,93758,1,0,1:0:0:0: +336,200,93923,5,0,1:0:0:0: +440,228,94087,1,0,1:0:0:0: +360,92,94252,1,0,1:0:0:0: +256,64,94417,1,0,1:0:0:0: +176,200,94582,5,2,1:2:0:0: +168,228,94664,1,0,1:0:0:0: +168,260,94747,1,0,1:0:0:0: +172,292,94829,1,0,1:0:0:0: +192,316,94912,1,0,1:0:0:0: +220,328,94994,1,0,1:0:0:0: +252,332,95076,1,0,1:0:0:0: +280,320,95159,1,0,1:0:0:0: +300,296,95241,2,0,L|308:248,3,45,2|0|0|0,1:2|1:0|1:0|1:0,0:0:0:0: +312,172,95571,2,0,L|304:127,3,45,0|0|0|0,1:0|1:0|1:0|1:0,0:0:0:0: +256,64,95901,6,0,P|208:56|164:60,1,90,4|0,1:2|0:0,0:0:0:0: +76,116,96230,1,8,0:0:0:0: +60,224,96395,1,0,0:0:0:0: +60,224,96477,1,0,0:0:0:0: +160,184,96642,1,0,0:0:0:0: +160,184,96725,1,0,1:0:0:0: +63,26,96890,2,0,L|76:116,1,90,8|0,0:0|0:0,0:0:0:0: +136,272,97219,5,0,1:0:0:0: +168,268,97302,1,0,0:0:0:0: +200,264,97384,1,0,0:0:0:0: +232,260,97466,1,0,0:0:0:0: +264,256,97549,1,8,0:0:0:0: +384,136,97714,1,0,1:0:0:0: +376,168,97796,1,0,0:0:0:0: +380,200,97879,1,0,0:0:0:0: +392,228,97961,1,0,0:0:0:0: +416,248,98043,2,0,P|464:260|512:260,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +231,105,98538,6,0,L|188:116,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +376,56,98868,2,0,L|420:64,1,45,8|0,0:0|0:0,0:0:0:0: +384,136,99032,1,0,0:0:0:0: +384,136,99115,2,0,P|340:128|304:92,1,90,0|0,0:0|0:0,0:0:0:0: +303,18,99362,2,0,L|207:26,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +452,88,99857,5,0,1:0:0:0: +465,116,99939,1,0,0:0:0:0: +466,147,100021,1,0,0:0:0:0: +456,177,100104,1,0,0:0:0:0: +436,201,100186,2,0,P|416:213|389:216,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +320,188,100516,2,0,P|300:176|273:173,3,45,0|0|0|0,0:0|1:0|1:0|0:0,0:0:0:0: +204,200,100846,2,0,P|192:220|189:247,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +188,320,101175,6,0,P|143:322|100:310,1,90,0|0,1:0|0:0,0:0:0:0: +76,292,101423,1,0,0:0:0:0: +76,292,101505,1,8,0:0:0:0: +76,292,101587,2,0,L|72:248,1,45 +12,68,101835,2,0,L|6:24,2,45,0|0|0,0:0|0:0|1:0,0:0:0:0: +104,140,102164,2,0,L|171:132,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +224,124,102494,6,0,P|236:164|232:216,1,90,0|0,1:0|0:0,0:0:0:0: +288,296,102824,1,8,0:0:0:0: +288,296,102906,1,0,0:0:0:0: +288,296,102988,2,0,P|328:284|380:288,1,90,0|0,1:0|0:0,0:0:0:0: +404,304,103236,1,0,0:0:0:0: +424,328,103318,1,0,1:0:0:0: +448,188,103483,2,0,L|440:140,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +424,72,103813,5,0,1:0:0:0: +324,112,103977,1,0,0:0:0:0: +324,112,104060,1,0,0:0:0:0: +324,112,104142,2,0,P|280:116|232:104,1,90,8|0,0:0|0:0,0:0:0:0: +160,28,104472,1,0,0:0:0:0: +216,208,104637,1,0,1:0:0:0: +216,208,104719,1,0,0:0:0:0: +216,208,104802,1,8,0:0:0:0: +352,240,104966,1,0,0:0:0:0: +384,244,105049,1,0,0:0:0:0: +416,248,105131,6,0,L|460:240,4,45,0|0|0|0|8,1:0|0:0|0:0|0:0|0:0,0:0:0:0: +272,288,105626,1,0,1:0:0:0: +264,320,105708,1,0,0:0:0:0: +256,352,105791,2,0,L|204:356,5,30,0|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +156,332,106120,2,0,L|104:336,5,30,8|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +56,312,106450,5,4,1:2:0:0: +4,188,106615,1,0,0:0:0:0: +168,220,106780,2,0,P|127:232|79:228,1,90,8|0,0:0|0:0,0:0:0:0: +112,124,107109,1,0,0:0:0:0: +272,216,107274,2,0,L|264:316,1,90,0|8,1:0|0:0,0:0:0:0: +400,268,107604,1,0,0:0:0:0: +428,132,107769,5,0,1:0:0:0: +428,132,107851,1,0,0:0:0:0: +428,132,107934,1,0,0:0:0:0: +428,132,108016,1,0,0:0:0:0: +428,132,108098,1,8,0:0:0:0: +332,84,108263,2,0,P|288:80|232:88,1,90,0|0,1:0|0:0,0:0:0:0: +112,124,108593,1,0,1:0:0:0: +148,264,108758,1,8,0:0:0:0: +16,236,108923,1,0,0:0:0:0: +264,126,109087,6,0,L|272:216,1,90,0|0,1:0|0:0,0:0:0:0: +452,224,109417,2,0,L|460:320,1,90,8|0,0:0|0:0,0:0:0:0: +360,232,109747,1,0,0:0:0:0: +348,56,109912,1,0,1:0:0:0: +416,140,110076,1,8,0:0:0:0: +256,112,110241,2,0,P|212:120|160:112,1,90,0|0,0:0|1:0,0:0:0:0: +348,56,110571,6,0,L|331:150,1,90,0|8,0:0|0:0,0:0:0:0: +208,328,110901,2,0,L|191:239,1,90,0|0,1:0|0:0,0:0:0:0: +184,216,111148,1,0,1:0:0:0: +178,194,111230,1,0,1:0:0:0: +68,272,111395,1,8,0:0:0:0: +56,136,111560,1,0,1:0:0:0: +178,194,111725,6,0,P|219:203|267:199,1,90,4|0,1:2|0:0,0:0:0:0: +364,148,112054,1,8,0:0:0:0: +384,256,112219,2,0,P|406:291|443:322,1,90,0|0,0:0|0:0,0:0:0:0: +488,224,112549,1,0,1:0:0:0: +304,232,112714,2,0,L|208:224,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +208,328,113208,6,0,L|112:320,1,90,0|8,0:0|0:0,0:0:0:0: +26,184,113538,2,0,L|116:192,1,90,0|0,1:0|0:0,0:0:0:0: +304,232,113868,1,0,1:0:0:0: +116,192,114032,1,8,0:0:0:0: +224,132,114197,1,0,0:0:0:0: +208,328,114362,6,0,B|272:360|320:312|320:312|340:368,1,180,4|8,1:2|0:0,0:0:0:0: +304,232,114857,2,0,P|300:184|308:140,1,90,0|0,0:0|0:0,0:0:0:0: +384,64,115186,1,0,1:0:0:0: +307,143,115351,1,8,0:0:0:0: +256,48,115516,1,0,0:0:0:0: +456,24,115681,6,0,B|482:101|420:136|420:136|440:184,1,180,4|8,1:2|0:0,0:0:0:0: +384,64,116175,2,0,P|340:56|296:64,1,90,0|0,1:0|0:0,0:0:0:0: +211,171,116505,1,0,1:0:0:0: +439,181,116670,2,0,L|448:84,1,90,8|0,0:0|0:0,0:0:0:0: +372,296,116999,6,2,L|304:292,1,67.5000025749208,2|0,0:1|0:0,0:0:0:0: +136,252,117329,6,2,P|196:260|212:172,1,168.75,0|0,0:0|0:0,0:0:0:0: +192,148,117659,1,2,0:3:0:0: +164,132,117741,1,2,0:3:0:0: +132,124,117824,1,2,1:3:0:0: +100,132,117906,1,2,0:3:0:0: +72,148,117988,2,0,L|52:56,1,90,2|8,0:3|0:0,0:0:0:0: +36,244,118318,5,0,1:0:0:0: +76,344,118483,1,0,1:0:0:0: +184,352,118648,1,0,1:0:0:0: +244,264,118813,1,0,1:0:0:0: +244,264,118895,1,0,1:0:0:0: +244,264,118977,2,0,L|288:260,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +332,328,119307,2,0,L|376:324,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +412,252,119637,5,4,1:2:0:0: +256,192,119719,12,0,122274,0:0:0:0: +256,192,140735,6,0,L|228:156,1,45,4|0,1:2|0:0,0:0:0:0: +152,132,141065,2,0,P|129:129|104:136,1,45 +48,192,141395,2,0,P|40:236|52:280,1,90,8|8,0:0|0:0,0:0:0:0: +196,352,142054,6,0,L|308:340,1,90,8|8,0:0|1:2,0:0:0:0: +336,280,142549,1,0,0:0:0:0: +404,324,142713,1,8,0:0:0:0: +404,324,142878,1,8,0:0:0:0: +292,120,143373,5,0,1:0:0:0: +212,104,143538,1,0,0:0:0:0: +140,140,143702,1,0,0:0:0:0: +120,220,143867,1,0,0:0:0:0: +144,296,144032,2,0,P|184:320|228:316,1,90,10|8,0:0|0:0,0:0:0:0: +372,212,144691,6,0,P|327:209|290:232,1,90,10|8,0:0|1:2,0:0:0:0: +348,288,145186,1,0,0:0:0:0: +452,220,145351,1,10,0:0:0:0: +452,220,145516,1,8,0:0:0:0: +328,36,146010,5,2,1:2:0:0: +264,88,146175,1,0,0:0:0:0: +184,108,146340,1,0,0:0:0:0: +104,88,146505,1,0,0:0:0:0: +44,36,146669,1,8,0:0:0:0: +44,36,146999,1,8,0:0:0:0: +44,36,147329,6,0,L|24:84,1,45,8|0,0:0|0:0,0:0:0:0: +52,156,147658,2,0,L|71:204,1,45,8|0,1:2|0:0,0:0:0:0: +144,236,147988,1,8,0:0:0:0: +144,236,148153,1,8,0:0:0:0: +316,64,148647,5,0,1:0:0:0: +380,116,148812,1,0,0:0:0:0: +408,192,148977,1,0,0:0:0:0: +380,268,149142,1,0,0:0:0:0: +316,320,149307,2,0,L|224:316,1,90,10|8,0:0|0:0,0:0:0:0: +64,248,149966,5,10,0:0:0:0: +144,236,150131,1,0,0:0:0:0: +188,168,150296,1,8,1:2:0:0: +192,88,150461,1,0,0:0:0:0: +140,24,150626,2,0,P|120:16|96:20,1,45,10|0,0:0|0:0,0:0:0:0: +260,132,150955,2,0,P|280:140|304:136,1,45,2|0,0:0|0:0,0:0:0:0: +476,48,151285,6,0,L|484:160,1,112.5,4|0,1:2|0:0,0:0:0:0: +464,236,151779,1,0,0:0:0:0: +436,308,151944,2,0,P|380:320|324:308,1,112.5,8|8,0:0|0:0,0:0:0:0: +76,308,152604,6,0,P|132:320|188:308,1,112.5,8|8,0:0|1:2,0:0:0:0: +256,88,153263,1,8,0:0:0:0: +256,168,153428,1,8,0:0:0:0: +256,168,153922,5,4,1:2:0:0: +256,248,154087,1,0,0:0:0:0: +324,128,154252,1,0,0:0:0:0: +188,128,154417,1,0,0:0:0:0: +332,212,154582,2,0,L|388:204,1,56.25,10|0,0:0|0:0,0:0:0:0: +492,152,154911,2,0,L|436:144,1,56.25,8|0,0:0|0:0,0:0:0:0: +324,128,155241,5,10,0:0:0:0: +180,212,155406,1,0,0:0:0:0: +332,212,155571,1,8,1:2:0:0: +188,128,155735,1,0,0:0:0:0: +256,248,155900,1,10,0:0:0:0: +256,248,156065,2,0,L|256:304,2,56.25,0|0|0,0:0|0:0|0:0,0:0:0:0: +180,212,156560,6,0,L|124:204,1,56.25,4|0,1:2|0:0,0:0:0:0: +20,152,156889,2,0,L|76:144,1,56.25,0|0,0:0|0:0,0:0:0:0: +188,128,157219,2,0,P|212:72|192:16,1,112.5,8|8,0:0|0:0,0:0:0:0: +132,72,157713,1,0,0:0:0:0: +180,212,157878,6,0,L|236:208,1,56.25,8|0,0:0|0:0,0:0:0:0: +360,252,158208,2,8,L|304:248,1,56.25,8|0,1:2|0:0,0:0:0:0: +168,292,158538,2,0,L|160:356,2,56.25,8|8|0,0:0|0:0|0:0,0:0:0:0: +180,212,159032,1,0,0:0:0:0: +144,140,159197,6,0,P|104:128|36:148,1,112.5,2|0,1:2|0:0,0:0:0:0: +12,220,159691,1,0,0:0:0:0: +36,296,159856,2,0,P|60:316|92:324,1,56.25,8|0,0:0|0:0,0:0:0:0: +215,264,160186,2,0,P|189:273|168:292,1,56.25,8|0,0:0|0:0,0:0:0:0: +228,344,160516,6,0,L|284:340,1,56.25,10|0,0:0|0:0,0:0:0:0: +328,276,160845,2,0,L|384:272,1,56.25,8|0,1:2|0:0,0:0:0:0: +428,208,161175,1,8,0:0:0:0: +440,128,161340,1,8,0:0:0:0: +400,60,161505,1,2,0:0:0:0: +328,28,161669,1,0,0:0:0:0: +212,76,161834,6,0,P|200:120|208:164,1,90,2|0,1:2|1:0,0:0:0:0: +300,308,162163,2,0,P|312:264|304:220,1,90,2|0,1:2|1:0,0:0:0:0: +140,236,162493,2,0,P|184:248|228:240,1,90,2|0,1:2|1:0,0:0:0:0: +372,148,162823,2,0,P|328:136|284:144,1,90,2|0,1:2|1:0,0:0:0:0: +104,316,163152,5,2,1:2:0:0: +78,297,163235,1,0,1:0:0:0: +60,270,163317,1,0,1:0:0:0: +54,239,163399,1,0,1:0:0:0: +58,207,163482,1,2,1:2:0:0: +74,180,163564,1,0,1:0:0:0: +98,159,163647,1,0,1:0:0:0: +127,149,163729,1,0,1:0:0:0: +158,150,163812,2,0,L|208:160,1,45,2|0,1:2|1:0,0:0:0:0: +344,184,163976,2,0,L|294:194,1,45,0|0,1:0|1:0,0:0:0:0: +140,236,164141,1,4,1:2:0:0: +140,236,164471,6,0,L|232:252,1,90,4|0,1:2|0:0,0:0:0:0: +344,184,164801,1,8,0:0:0:0: +380,284,164965,1,0,0:0:0:0: +368,104,165130,2,0,P|324:104|284:128,1,90,0|0,0:0|1:0,0:0:0:0: +356,360,165460,2,0,P|400:360|440:336,1,90,8|0,0:0|0:0,0:0:0:0: +432,208,165790,5,0,1:0:0:0: +292,260,165954,1,0,0:0:0:0: +344,184,166119,1,8,0:0:0:0: +204,236,166284,1,0,1:0:0:0: +204,236,166366,1,0,0:0:0:0: +204,236,166449,2,0,L|216:328,1,90,0|0,0:0|1:0,0:0:0:0: +120,208,166779,2,0,L|131:118,1,90,8|0,0:0|0:0,0:0:0:0: +204,236,167108,5,0,1:0:0:0: +32,216,167273,1,0,0:0:0:0: +130,118,167438,1,8,0:0:0:0: +110,298,167603,1,0,0:0:0:0: +110,298,167685,1,0,0:0:0:0: +110,298,167768,2,0,L|121:208,1,90,0|0,0:0|1:0,0:0:0:0: +304,40,168097,2,0,L|315:130,1,90,8|0,0:0|0:0,0:0:0:0: +328,236,168427,5,0,1:0:0:0: +184,148,168592,1,0,0:0:0:0: +314,129,168757,1,8,0:0:0:0: +197,254,168921,1,0,1:0:0:0: +197,254,169004,1,0,0:0:0:0: +197,254,169086,2,0,P|220:292|260:312,1,90,0|0,0:0|1:0,0:0:0:0: +409,210,169416,2,0,P|365:211|328:236,1,90,8|0,0:0|0:0,0:0:0:0: +488,232,169746,6,0,P|487:192|464:149,1,90,0|0,1:0|0:0,0:0:0:0: +314,129,170075,1,8,0:0:0:0: +409,210,170240,1,0,0:0:0:0: +332,40,170405,2,0,L|240:36,1,90,0|0,0:0|1:0,0:0:0:0: +68,144,170735,2,0,L|157:140,1,90,8|0,0:0|0:0,0:0:0:0: +314,129,171064,5,0,1:0:0:0: +332,40,171229,1,0,0:0:0:0: +324,216,171394,1,8,0:0:0:0: +306,305,171559,1,0,1:0:0:0: +257,178,171724,1,0,0:0:0:0: +168,160,171888,1,0,1:0:0:0: +384,164,172053,1,8,0:0:0:0: +473,182,172218,1,0,0:0:0:0: +306,305,172383,6,0,L|216:312,1,90,0|0,1:0|0:0,0:0:0:0: +60,172,172713,1,8,0:0:0:0: +120,260,172877,1,0,0:0:0:0: +168,160,173042,2,0,L|172:68,1,90,0|0,0:0|1:0,0:0:0:0: +309,216,173372,2,0,L|306:306,1,90,8|0,0:0|0:0,0:0:0:0: +120,260,173702,5,0,1:0:0:0: +152,256,173784,1,0,1:0:0:0: +184,252,173866,1,0,1:0:0:0: +309,216,174031,1,8,0:0:0:0: +103,168,174196,1,0,1:0:0:0: +135,164,174279,1,0,1:0:0:0: +167,160,174361,1,0,1:0:0:0: +292,124,174526,1,0,1:0:0:0: +87,76,174691,1,8,1:2:0:0: +119,72,174773,1,0,1:0:0:0: +151,68,174855,1,0,1:0:0:0: +276,32,175020,6,0,L|368:40,1,90,0|0,1:0|0:0,0:0:0:0: +448,108,175350,1,8,0:0:0:0: +292,124,175515,1,0,0:0:0:0: +292,124,175597,1,0,0:0:0:0: +292,124,175680,2,0,L|308:216,1,90,0|0,0:0|1:0,0:0:0:0: +328,320,176009,1,8,0:0:0:0: +408,248,176174,1,0,0:0:0:0: +220,300,176339,6,0,P|176:304|128:292,1,90,0|0,1:0|0:0,0:0:0:0: +16,120,176669,1,8,0:0:0:0: +120,152,176834,1,0,1:0:0:0: +120,152,176916,1,0,0:0:0:0: +120,152,176998,2,0,L|124:200,1,45 +212,176,177163,2,0,L|239:215,1,45,0|0,1:0|0:0,0:0:0:0: +292,124,177328,2,0,P|302:79|283:30,1,90,8|0,0:0|0:0,0:0:0:0: +344,192,177658,6,0,P|372:156|376:104,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,177987,1,8,0:0:0:0: +272,228,178152,1,0,0:0:0:0: +272,228,178235,1,0,0:0:0:0: +272,228,178317,1,0,0:0:0:0: +292,124,178482,1,0,1:0:0:0: +180,180,178647,1,8,0:0:0:0: +200,284,178812,1,0,0:0:0:0: +292,124,178976,5,0,1:0:0:0: +288,92,179059,1,0,0:0:0:0: +280,60,179141,2,0,P|248:24|208:14,1,90,0|8,0:0|0:0,0:0:0:0: +22,65,179471,2,0,P|67:71|112:68,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,179801,1,0,1:0:0:0: +22,65,179965,1,8,0:0:0:0: +180,180,180130,5,0,0:0:0:0: +180,180,180213,1,0,0:0:0:0: +180,180,180295,2,0,P|184:224|172:272,1,90,0|0,1:0|0:0,0:0:0:0: +76,216,180625,2,0,P|72:172|84:124,1,90,8|0,0:0|0:0,0:0:0:0: +380,240,180954,2,0,P|384:284|372:332,1,90,0|0,0:0|1:0,0:0:0:0: +276,276,181284,2,0,P|272:232|284:184,1,90,8|0,0:0|0:0,0:0:0:0: +374,129,181614,5,0,1:0:0:0: +300,352,181779,2,0,L|204:348,2,90,0|8|0,0:0|0:0|1:0,0:0:0:0: +448,180,182273,1,2,0:0:0:0: +448,180,182438,1,2,1:2:0:0: +276,276,182603,1,10,0:0:0:0: +276,276,182768,1,2,0:0:0:0: +96,200,182932,6,0,L|88:108,1,90,0|0,1:0|0:0,0:0:0:0: +96,200,183262,1,8,0:0:0:0: +12,68,183427,2,0,P|72:24|164:68,1,180,0|0,0:0|1:0,0:0:0:0: +140,272,183921,2,0,P|92:284|52:271,1,90,8|0,0:0|0:0,0:0:0:0: +176,156,184251,5,0,1:0:0:0: +208,152,184334,1,0,1:0:0:0: +240,148,184416,1,0,1:0:0:0: +308,64,184581,1,8,0:0:0:0: +296,240,184746,1,0,1:0:0:0: +312,268,184828,1,0,1:0:0:0: +336,284,184910,1,0,1:0:0:0: +368,292,184993,1,0,1:0:0:0: +400,288,185075,1,0,1:0:0:0: +464,184,185240,1,8,0:0:0:0: +468,152,185323,1,0,0:0:0:0: +472,120,185405,2,0,L|464:76,1,45,0|0,1:0|1:0,0:0:0:0: +388,96,185570,6,0,P|360:132|316:148,1,90,4|0,1:2|0:0,0:0:0:0: +224,46,185899,2,0,P|268:43|308:63,1,90,8|0,0:0|0:0,0:0:0:0: +296,240,186229,1,0,0:0:0:0: +308,64,186394,1,0,1:0:0:0: +296,240,186559,2,0,L|312:332,1,90,8|0,0:0|0:0,0:0:0:0: +464,184,186888,6,0,P|420:180|372:188,1,90,0|0,1:0|0:0,0:0:0:0: +296,240,187218,1,8,0:0:0:0: +136,292,187383,2,0,P|94:277|54:249,1,90,0|0,1:0|0:0,0:0:0:0: +21,159,187713,1,0,1:0:0:0: +104,8,187877,2,0,L|124:96,1,90,10|0,0:0|0:0,0:0:0:0: +124,96,188207,6,0,P|152:132|196:148,1,90,0|0,1:0|0:0,0:0:0:0: +287,46,188537,2,0,P|243:43|204:63,1,90,8|0,0:0|0:0,0:0:0:0: +216,240,188866,1,2,0:0:0:0: +204,64,189031,1,0,1:0:0:0: +216,240,189196,2,0,L|200:332,1,90,8|0,0:0|0:0,0:0:0:0: +40,240,189526,5,2,1:2:0:0: +128,192,189691,1,0,0:0:0:0: +216,240,189855,1,8,0:0:0:0: +304,192,190020,1,0,1:0:0:0: +392,240,190185,2,0,L|400:332,1,90,2|0,0:0|1:0,0:0:0:0: +464,168,190515,2,0,L|456:76,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,190844,6,0,P|364:272|312:292,1,90,2|0,1:2|0:0,0:0:0:0: +220,140,191174,2,0,P|248:108|296:92,1,90,8|0,0:0|0:0,0:0:0:0: +324,96,191421,1,0,0:0:0:0: +356,104,191504,2,0,L|340:16,1,90,0|0,0:0|1:0,0:0:0:0: +256,276,191834,2,0,L|272:364,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,192163,5,0,1:0:0:0: +356,104,192328,1,0,0:0:0:0: +220,140,192493,1,8,0:0:0:0: +256,276,192658,1,0,1:0:0:0: +305,191,192823,1,0,0:0:0:0: +212,56,192987,1,0,1:0:0:0: +200,220,193152,1,10,0:0:0:0: +200,220,193482,6,0,P|156:228|108:220,1,90,0|0,1:0|0:0,0:0:0:0: +88,116,193812,1,8,0:0:0:0: +16,192,193976,1,0,0:0:0:0: +16,192,194059,1,0,0:0:0:0: +16,192,194141,2,0,L|28:288,1,90,2|0,0:0|1:0,0:0:0:0: +188,309,194471,2,0,L|200:220,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,194801,5,2,1:2:0:0: +216,112,194883,1,0,1:0:0:0: +216,112,194965,1,0,1:0:0:0: +361,25,195130,1,8,0:0:0:0: +294,180,195295,1,0,1:0:0:0: +294,180,195377,1,0,1:0:0:0: +294,180,195460,1,2,0:0:0:0: +256,16,195625,1,0,1:0:0:0: +384,127,195790,1,10,1:2:0:0: +416,132,195872,1,0,1:0:0:0: +448,140,195954,2,0,L|452:84,1,45,0|0,1:0|1:0,0:0:0:0: +416,216,196119,6,0,P|412:264|432:312,1,90,4|0,1:2|0:0,0:0:0:0: +304,268,196449,2,0,P|308:220|288:172,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,196779,2,0,L|120:104,1,90,0|0,0:0|1:0,0:0:0:0: +52,248,197108,2,0,L|141:255,1,90,8|0,0:0|0:0,0:0:0:0: +304,268,197438,5,0,1:0:0:0: +416,216,197603,1,0,0:0:0:0: +408,340,197768,1,8,0:0:0:0: +332,180,197932,1,0,1:0:0:0: +332,180,198015,1,0,0:0:0:0: +332,180,198097,2,0,P|360:140|400:120,1,90,0|0,0:0|1:0,0:0:0:0: +484,284,198427,1,10,0:0:0:0: +304,268,198592,1,2,0:0:0:0: +416,216,198757,6,0,P|428:172|420:124,1,90,2|0,1:2|0:0,0:0:0:0: +344,52,199086,1,8,0:0:0:0: +332,180,199251,1,0,0:0:0:0: +164,236,199416,2,0,P|152:192|160:144,1,90,0|0,0:0|1:0,0:0:0:0: +236,72,199746,1,8,0:0:0:0: +248,200,199910,1,0,0:0:0:0: +156,328,200075,6,0,L|56:320,1,90,2|0,1:2|0:0,0:0:0:0: +164,236,200405,1,8,0:0:0:0: +256,292,200570,2,0,P|300:296|344:284,1,90,0|0,1:0|0:0,0:0:0:0: +432,220,200899,2,0,L|460:308,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +392,120,201394,5,4,1:2:0:0: +396,32,201559,1,0,1:0:0:0: +316,72,201724,1,0,1:0:0:0: +256,6,201888,1,0,1:0:0:0: +228,91,202053,1,0,1:0:0:0: +139,87,202218,1,0,1:0:0:0: +179,166,202383,1,0,1:0:0:0: +113,226,202548,1,0,1:0:0:0: +197,253,202713,5,4,1:2:0:0: +193,342,202877,1,0,1:0:0:0: +272,302,203042,1,0,1:0:0:0: +332,367,203207,1,0,1:0:0:0: +359,283,203372,1,2,1:2:0:0: +448,287,203537,1,2,1:2:0:0: +407,208,203702,1,2,1:2:0:0: +472,147,203866,1,2,1:2:0:0: +387,121,204031,5,4,1:2:0:0: +360,100,204114,1,0,1:0:0:0: +344,72,204196,1,0,1:0:0:0: +336,40,204279,1,0,1:0:0:0: +340,8,204361,1,0,1:0:0:0: +316,28,204443,1,0,1:0:0:0: +284,32,204526,1,0,1:0:0:0: +252,28,204608,1,0,1:0:0:0: +228,8,204691,2,0,L|184:20,7,45,4|0|0|0|0|0|0|0,1:2|1:0|1:0|1:0|1:0|1:0|1:0|1:0,0:0:0:0: +112,56,205350,5,4,1:2:0:0: +100,84,205432,1,0,1:0:0:0: +96,116,205515,1,0,1:0:0:0: +100,148,205597,1,0,1:0:0:0: +112,176,205680,1,0,1:0:0:0: +124,204,205762,1,0,1:0:0:0: +128,236,205844,1,0,1:0:0:0: +124,268,205927,1,0,1:0:0:0: +112,296,206009,2,0,L|71:313,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +192,312,206339,2,0,L|175:353,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +256,264,206669,5,4,1:2:0:0: +256,192,206751,12,0,209306,0:0:0:0: diff --git a/osu.Game.Tests/app.config b/osu.Game.Tests/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Tests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj new file mode 100644 index 0000000000..8ebd38022e --- /dev/null +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -0,0 +1,103 @@ + + + + Debug + AnyCPU + {54377672-20B1-40AF-8087-5CF73BF3953A} + Library + osu.Game.Tests + osu.Game.Tests + v4.6.1 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + false + 6 + + + true + bin\Release + prompt + 4 + false + false + + + + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll + True + + + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + True + + + + $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll + + + $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll + + + $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll + + + + + osu.licenseheader + + + + + + + + {c76bf5b3-985e-4d39-95fe-97c9c879b83a} + osu.Framework + + + {c92a607b-1fdd-4954-9f92-03ff547d9080} + osu.Game.Rulesets.Osu + + + {58f6c80c-1253-4a0e-a465-b8c85ebeadf3} + osu.Game.Rulesets.Catch + + + {48f4582b-7687-4621-9cbe-5c24197cb536} + osu.Game.Rulesets.Mania + + + {f167e17a-7de6-4af5-b920-a5112296c695} + osu.Game.Rulesets.Taiko + + + {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} + osu.Game + + + {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58} + osu.Game.Resources + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config new file mode 100644 index 0000000000..af47f642e3 --- /dev/null +++ b/osu.Game.Tests/packages.config @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/osu.sln b/osu.sln index ccef0c370c..2b1a0aa0e5 100644 --- a/osu.sln +++ b/osu.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Mania", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.Deploy", "osu.Desktop.Deploy\osu.Desktop.Deploy.csproj", "{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tests", "osu.Game.Tests\osu.Game.Tests.csproj", "{54377672-20B1-40AF-8087-5CF73BF3953A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +73,12 @@ Global {BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Release|Any CPU.ActiveCfg = Release|Any CPU {BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.VisualTests|Any CPU.ActiveCfg = Debug|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.Build.0 = Release|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.VisualTests|Any CPU.ActiveCfg = Release|Any CPU + {54377672-20B1-40AF-8087-5CF73BF3953A}.VisualTests|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From b6a6042b5c9c6077e5c83f7f0e8806f1be0acdc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 13:09:06 +0800 Subject: [PATCH 78/96] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index e1352a8b0b..5f3a7fe4d0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit e1352a8b0b5d1ba8acd9335a56c714d2ccc2f6a6 +Subproject commit 5f3a7fe4d0537820a33b817a41623b4b22a3ec59 From 09968671129fd5bf97d309744571a68ace8af67f Mon Sep 17 00:00:00 2001 From: Damnae Date: Mon, 25 Sep 2017 10:40:22 +0200 Subject: [PATCH 79/96] Move StoryboardReplacesBackground and StoryboardAspect properties to Storyboard. --- osu.Game/Beatmaps/Beatmap.cs | 15 --------------- osu.Game/Beatmaps/BeatmapInfo.cs | 1 - osu.Game/Screens/Play/Player.cs | 4 ++-- osu.Game/Storyboards/Storyboard.cs | 16 ++++++++++++++++ osu.Game/Tests/Visual/TestCaseStoryboard.cs | 4 +++- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 84db2f9943..458c2304f2 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -46,21 +46,6 @@ namespace osu.Game.Beatmaps /// public Storyboard Storyboard = new Storyboard(); - /// - /// Whether this beatmap's background should be hidden while its storyboard is being displayed. - /// - public bool StoryboardReplacesBackground - { - get - { - var backgroundPath = BeatmapInfo.BeatmapSet?.Metadata?.BackgroundFile?.ToLowerInvariant(); - if (backgroundPath == null) - return false; - - return Storyboard.GetLayer("Background").Elements.Any(e => e.Path.ToLowerInvariant() == backgroundPath); - } - } - /// /// Constructs a new beatmap. /// diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 2dc4b44ed7..0776669811 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -75,7 +75,6 @@ namespace osu.Game.Beatmaps public bool LetterboxInBreaks { get; set; } public bool WidescreenStoryboard { get; set; } - public float StoryboardAspect => WidescreenStoryboard ? 16 / 9f : 4 / 3f; // Editor // This bookmarks stuff is necessary because DB doesn't know how to store int[] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fd1eeaa395..75a5dd8f7d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -232,10 +232,10 @@ namespace osu.Game.Screens.Play var beatmap = Beatmap.Value.Beatmap; storyboard = beatmap.Storyboard.CreateDrawable(); - storyboard.Width = storyboard.Height * beatmap.BeatmapInfo.StoryboardAspect; + storyboard.Width = storyboard.Height * beatmap.Storyboard.AspectRatio(beatmap.BeatmapInfo); storyboard.Masking = true; - if (!beatmap.StoryboardReplacesBackground) + if (!beatmap.Storyboard.ReplacesBackground(beatmap.BeatmapInfo)) storyboard.BackgroundTexture = Beatmap.Value.Background; storyboardContainer.Add(asyncLoad ? new AsyncLoadWrapper(storyboard) { RelativeSizeAxes = Axes.Both } : (Drawable)storyboard); } diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 2e7188f28c..f74074e977 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.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.Game.Beatmaps; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; @@ -31,6 +32,21 @@ namespace osu.Game.Storyboards return layer; } + /// + /// Whether the beatmap's background should be hidden while this storyboard is being displayed. + /// + public bool ReplacesBackground(BeatmapInfo beatmapInfo) + { + var backgroundPath = beatmapInfo.BeatmapSet?.Metadata?.BackgroundFile?.ToLowerInvariant(); + if (backgroundPath == null) + return false; + + return GetLayer("Background").Elements.Any(e => e.Path.ToLowerInvariant() == backgroundPath); + } + + public float AspectRatio(BeatmapInfo beatmapInfo) + => beatmapInfo.WidescreenStoryboard ? 16 / 9f : 4 / 3f; + public DrawableStoryboard CreateDrawable() => new DrawableStoryboard(this); } diff --git a/osu.Game/Tests/Visual/TestCaseStoryboard.cs b/osu.Game/Tests/Visual/TestCaseStoryboard.cs index c9601ffefc..75e23db475 100644 --- a/osu.Game/Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Game/Tests/Visual/TestCaseStoryboard.cs @@ -83,7 +83,9 @@ namespace osu.Game.Tests.Visual storyboard = working.Beatmap.Storyboard.CreateDrawable(); storyboard.Passing = false; - if (!working.Beatmap.StoryboardReplacesBackground) + + var beatmap = working.Beatmap; + if (!beatmap.Storyboard.ReplacesBackground(beatmap.BeatmapInfo)) storyboard.BackgroundTexture = working.Background; storyboardContainer.Add(storyboard); From d787c740fa22e83be06b4022814d8bb362084836 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Sep 2017 17:46:51 +0900 Subject: [PATCH 80/96] Fix bookmarks not working We should be dealing with the array in every situation, with the exception of the database. --- osu.Game/Beatmaps/BeatmapInfo.cs | 14 +++++++------- .../Screens/Edit/Components/SummaryTimeline.cs | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index e031f25fa2..3cd6294b4a 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -78,15 +78,15 @@ namespace osu.Game.Beatmaps // Editor // This bookmarks stuff is necessary because DB doesn't know how to store int[] - public string StoredBookmarks { get; set; } + [JsonIgnore] + public string StoredBookmarks + { + get { return string.Join(",", Bookmarks); } + set { Bookmarks = value?.Split(',').Select(v => int.Parse(v.Trim())).ToArray() ?? new int[0]; } + } [Ignore] - [JsonIgnore] - public int[] Bookmarks - { - get { return StoredBookmarks?.Split(',').Select(int.Parse).ToArray() ?? new int[0]; } - set { StoredBookmarks = string.Join(",", value); } - } + public int[] Bookmarks { get; set; } = new int[0]; public double DistanceSpacing { get; set; } public int BeatDivisor { get; set; } diff --git a/osu.Game/Screens/Edit/Components/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/SummaryTimeline.cs index ffb54ba7b1..80250eebc3 100644 --- a/osu.Game/Screens/Edit/Components/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/SummaryTimeline.cs @@ -96,6 +96,7 @@ namespace osu.Game.Screens.Edit.Components new BookmarkTimeline { Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.Both, Height = 0.35f }, From d86e81f07c860efdba6a407297d75cbd370d238b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Sep 2017 17:52:57 +0900 Subject: [PATCH 81/96] Better expression to avoid invalid values --- osu.Game/Beatmaps/BeatmapInfo.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3cd6294b4a..5e4e122fb5 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -82,7 +82,21 @@ namespace osu.Game.Beatmaps public string StoredBookmarks { get { return string.Join(",", Bookmarks); } - set { Bookmarks = value?.Split(',').Select(v => int.Parse(v.Trim())).ToArray() ?? new int[0]; } + set + { + if (string.IsNullOrEmpty(value)) + { + Bookmarks = new int[0]; + return; + } + + Bookmarks = value.Split(',').Select(v => + { + int val; + bool result = int.TryParse(v, out val); + return new { result, val }; + }).Where(p => p.result).Select(p => p.val).ToArray(); + } } [Ignore] From 2d4616fd43cb22ac7d6ae5d704651347238b017f Mon Sep 17 00:00:00 2001 From: Damnae Date: Mon, 25 Sep 2017 11:03:57 +0200 Subject: [PATCH 82/96] Apply beatmap settings when creating the DrawableStoryboard. --- osu.Game/Screens/Play/Player.cs | 5 +---- osu.Game/Storyboards/Storyboard.cs | 14 ++++++++++++-- osu.Game/Tests/Visual/TestCaseStoryboard.cs | 6 +----- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 75a5dd8f7d..e120c7f193 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -231,12 +231,9 @@ namespace osu.Game.Screens.Play { var beatmap = Beatmap.Value.Beatmap; - storyboard = beatmap.Storyboard.CreateDrawable(); - storyboard.Width = storyboard.Height * beatmap.Storyboard.AspectRatio(beatmap.BeatmapInfo); + storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); storyboard.Masking = true; - if (!beatmap.Storyboard.ReplacesBackground(beatmap.BeatmapInfo)) - storyboard.BackgroundTexture = Beatmap.Value.Background; storyboardContainer.Add(asyncLoad ? new AsyncLoadWrapper(storyboard) { RelativeSizeAxes = Axes.Both } : (Drawable)storyboard); } diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index f74074e977..59cbe74650 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -47,7 +47,17 @@ namespace osu.Game.Storyboards public float AspectRatio(BeatmapInfo beatmapInfo) => beatmapInfo.WidescreenStoryboard ? 16 / 9f : 4 / 3f; - public DrawableStoryboard CreateDrawable() - => new DrawableStoryboard(this); + public DrawableStoryboard CreateDrawable(WorkingBeatmap working = null) + { + var drawable = new DrawableStoryboard(this); + if (working != null) + { + var beatmapInfo = working.Beatmap.BeatmapInfo; + drawable.Width = drawable.Height * AspectRatio(beatmapInfo); + if (!ReplacesBackground(beatmapInfo)) + drawable.BackgroundTexture = working.Background; + } + return drawable; + } } } diff --git a/osu.Game/Tests/Visual/TestCaseStoryboard.cs b/osu.Game/Tests/Visual/TestCaseStoryboard.cs index 75e23db475..c6ef3f4ecf 100644 --- a/osu.Game/Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Game/Tests/Visual/TestCaseStoryboard.cs @@ -81,13 +81,9 @@ namespace osu.Game.Tests.Visual var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true }; storyboardContainer.Clock = decoupledClock; - storyboard = working.Beatmap.Storyboard.CreateDrawable(); + storyboard = working.Beatmap.Storyboard.CreateDrawable(beatmapBacking); storyboard.Passing = false; - var beatmap = working.Beatmap; - if (!beatmap.Storyboard.ReplacesBackground(beatmap.BeatmapInfo)) - storyboard.BackgroundTexture = working.Background; - storyboardContainer.Add(storyboard); decoupledClock.ChangeSource(working.Track); } From 5be11f539bbe56c53a6b451ffbb0f32931b35383 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 17:26:27 +0800 Subject: [PATCH 83/96] Rename to BeatmapSetOverlay --- .../AuthorInfo.cs | 6 ++--- .../BasicStats.cs | 4 +-- .../BeatmapPicker.cs | 6 ++--- .../Details.cs | 8 +++--- .../DownloadButton.cs | 4 +-- .../FavouriteButton.cs | 4 +-- .../Header.cs | 10 +++---- .../HeaderButton.cs | 2 +- .../{OnlineBeatmapSet => BeatmapSet}/Info.cs | 14 +++++----- .../PreviewButton.cs | 6 ++--- .../SuccessRate.cs | 6 ++--- ...tmapSetOverlay.cs => BeatmapSetOverlay.cs} | 6 ++--- ...verlay.cs => TestCaseBeatmapSetOverlay.cs} | 8 +++--- osu.Game/osu.Game.csproj | 26 +++++++++---------- 14 files changed, 55 insertions(+), 55 deletions(-) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/AuthorInfo.cs (95%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/BasicStats.cs (96%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/BeatmapPicker.cs (96%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/Details.cs (94%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/DownloadButton.cs (95%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/FavouriteButton.cs (95%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/Header.cs (96%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/HeaderButton.cs (93%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/Info.cs (93%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/PreviewButton.cs (95%) rename osu.Game/Overlays/{OnlineBeatmapSet => BeatmapSet}/SuccessRate.cs (96%) rename osu.Game/Overlays/{OnlineBeatmapSetOverlay.cs => BeatmapSetOverlay.cs} (91%) rename osu.Game/Tests/Visual/{TestCaseOnlineBeatmapSetOverlay.cs => TestCaseBeatmapSetOverlay.cs} (96%) diff --git a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs similarity index 95% rename from osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs rename to osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index ce46e96380..b0e4e49e31 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -1,16 +1,16 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Users; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class AuthorInfo : Container { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs similarity index 96% rename from osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs rename to osu.Game/Overlays/BeatmapSet/BasicStats.cs index 947bc111e0..885f9cc219 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -10,8 +9,9 @@ using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class BasicStats : Container { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs similarity index 96% rename from osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs rename to osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index d7b9fa49bd..2317e8562a 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -3,8 +3,6 @@ using System; using System.Linq; -using OpenTK; -using OpenTK.Graphics; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -18,8 +16,10 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class BeatmapPicker : Container { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs similarity index 94% rename from osu.Game/Overlays/OnlineBeatmapSet/Details.cs rename to osu.Game/Overlays/BeatmapSet/Details.cs index 958cc2cd18..2fd0a55d9e 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -1,16 +1,16 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Screens.Select.Details; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class Details : FillFlowContainer { @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet public Details() { - Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH; + Width = BeatmapSetOverlay.RIGHT_WIDTH; AutoSizeAxes = Axes.Y; Spacing = new Vector2(1f); diff --git a/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/DownloadButton.cs similarity index 95% rename from osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs rename to osu.Game/Overlays/BeatmapSet/DownloadButton.cs index 855aa3de93..18a0cfd968 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/DownloadButton.cs @@ -1,13 +1,13 @@ // 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.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class DownloadButton : HeaderButton { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/FavouriteButton.cs similarity index 95% rename from osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs rename to osu.Game/Overlays/BeatmapSet/FavouriteButton.cs index 4998ea1c19..9fd4ac177c 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/FavouriteButton.cs @@ -1,15 +1,15 @@ // 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.Game.Graphics; using osu.Game.Graphics.Backgrounds; +using OpenTK; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class FavouriteButton : HeaderButton { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs similarity index 96% rename from osu.Game/Overlays/OnlineBeatmapSet/Header.cs rename to osu.Game/Overlays/BeatmapSet/Header.cs index 2cd07b2212..a93ccbf704 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -13,8 +11,10 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class Header : Container { @@ -124,7 +124,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = OnlineBeatmapSetOverlay.X_PADDING }, + Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = BeatmapSetOverlay.X_PADDING }, Child = new FillFlowContainer { RelativeSizeAxes = Axes.Both, @@ -196,7 +196,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, - Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.X_PADDING }, + Margin = new MarginPadding { Right = BeatmapSetOverlay.X_PADDING }, }, }, }, diff --git a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/HeaderButton.cs similarity index 93% rename from osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs rename to osu.Game/Overlays/BeatmapSet/HeaderButton.cs index fe852ec83a..3075020fe6 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/HeaderButton.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class HeaderButton : OsuClickableContainer { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs similarity index 93% rename from osu.Game/Overlays/OnlineBeatmapSet/Info.cs rename to osu.Game/Overlays/BeatmapSet/Info.cs index 7782e8b7ab..4a59591a72 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -11,8 +9,10 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class Info : Container { @@ -67,13 +67,13 @@ namespace osu.Game.Overlays.OnlineBeatmapSet new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 15, Horizontal = OnlineBeatmapSetOverlay.X_PADDING }, + Padding = new MarginPadding { Top = 15, Horizontal = BeatmapSetOverlay.X_PADDING }, Children = new Drawable[] { new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = metadata_width + OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing * 2 }, + Padding = new MarginPadding { Right = metadata_width + BeatmapSetOverlay.RIGHT_WIDTH + spacing * 2 }, Child = new ScrollContainer { RelativeSizeAxes = Axes.Both, @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Width = metadata_width, ScrollbarVisible = false, Padding = new MarginPadding { Horizontal = 10 }, - Margin = new MarginPadding { Right = OnlineBeatmapSetOverlay.RIGHT_WIDTH + spacing }, + Margin = new MarginPadding { Right = BeatmapSetOverlay.RIGHT_WIDTH + spacing }, Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -108,7 +108,7 @@ namespace osu.Game.Overlays.OnlineBeatmapSet Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, - Width = OnlineBeatmapSetOverlay.RIGHT_WIDTH, + Width = BeatmapSetOverlay.RIGHT_WIDTH, Children = new Drawable[] { successRateBackground = new Box diff --git a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs similarity index 95% rename from osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs rename to osu.Game/Overlays/BeatmapSet/PreviewButton.cs index b8673e2a77..bdb06106f0 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -15,8 +13,10 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class PreviewButton : OsuClickableContainer { diff --git a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs similarity index 96% rename from osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs rename to osu.Game/Overlays/BeatmapSet/SuccessRate.cs index 3389542e64..26335aac9b 100644 --- a/osu.Game/Overlays/OnlineBeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -1,17 +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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Beatmaps; using osu.Game.Screens.Select.Details; -using System; -namespace osu.Game.Overlays.OnlineBeatmapSet +namespace osu.Game.Overlays.BeatmapSet { public class SuccessRate : Container { diff --git a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs similarity index 91% rename from osu.Game/Overlays/OnlineBeatmapSetOverlay.cs rename to osu.Game/Overlays/BeatmapSetOverlay.cs index 8db211e352..d809bc6727 100644 --- a/osu.Game/Overlays/OnlineBeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,11 +10,11 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.OnlineBeatmapSet; +using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Overlays { - public class OnlineBeatmapSetOverlay : WaveOverlayContainer + public class BeatmapSetOverlay : WaveOverlayContainer { public const float X_PADDING = 40; public const float RIGHT_WIDTH = 275; @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private readonly Header header; private readonly Info info; - public OnlineBeatmapSetOverlay() + public BeatmapSetOverlay() { FirstWaveColour = OsuColour.Gray(0.4f); SecondWaveColour = OsuColour.Gray(0.3f); diff --git a/osu.Game/Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs b/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs similarity index 96% rename from osu.Game/Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs rename to osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs index 71113b5478..76ed9979ca 100644 --- a/osu.Game/Tests/Visual/TestCaseOnlineBeatmapSetOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBeatmapSetOverlay.cs @@ -12,15 +12,15 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual { - internal class TestCaseOnlineBeatmapSetOverlay : OsuTestCase + internal class TestCaseBeatmapSetOverlay : OsuTestCase { public override string Description => @"view online beatmap sets"; - private readonly OnlineBeatmapSetOverlay overlay; + private readonly BeatmapSetOverlay overlay; - public TestCaseOnlineBeatmapSetOverlay() + public TestCaseBeatmapSetOverlay() { - Add(overlay = new OnlineBeatmapSetOverlay()); + Add(overlay = new BeatmapSetOverlay()); } [BackgroundDependencyLoader] diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 659af88b3f..ddb29c63c3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -774,19 +774,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + From c2bb3ea7bcad14034fa98cf565b7807582018b12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 17:58:03 +0800 Subject: [PATCH 84/96] Add minimal viable implementation of BeatmapSetOver in game --- osu.Game/OsuGame.cs | 4 ++++ osu.Game/Overlays/BeatmapSetOverlay.cs | 1 - osu.Game/Overlays/Direct/DirectGridPanel.cs | 7 ------- osu.Game/Overlays/Direct/DirectPanel.cs | 12 +++++++++++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b4fbdfb252..c137b8f6f5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -47,6 +47,8 @@ namespace osu.Game private UserProfileOverlay userProfile; + private BeatmapSetOverlay beatmapSetOverlay; + public virtual Storage GetStorageForStableInstall() => null; private Intro intro @@ -187,6 +189,7 @@ namespace osu.Game Depth = -1 }, overlayContent.Add); LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add); + LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -2 }, mainContent.Add); LoadComponentAsync(musicController = new MusicController { Depth = -3, @@ -223,6 +226,7 @@ namespace osu.Game dependencies.Cache(chat); dependencies.Cache(userProfile); dependencies.Cache(musicController); + dependencies.Cache(beatmapSetOverlay); dependencies.Cache(notificationOverlay); dependencies.Cache(dialogOverlay); diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index d809bc6727..6915523975 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -86,7 +86,6 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { header.BeatmapSet = info.BeatmapSet = set; - Show(); } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 3a9e75bd38..0cc1c18d8d 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.Input; namespace osu.Game.Overlays.Direct { @@ -172,11 +171,5 @@ namespace osu.Game.Overlays.Direct }, }); } - - protected override bool OnClick(InputState state) - { - StartDownload(); - return true; - } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 6f1f581d0b..4f7f1bb39e 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -37,6 +37,7 @@ namespace osu.Game.Overlays.Direct private ProgressBar progressBar; private BeatmapManager beatmaps; private NotificationOverlay notifications; + private BeatmapSetOverlay beatmapSetOverlay; protected override Container Content => content; @@ -63,11 +64,12 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) + private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications, BeatmapSetOverlay beatmapSetOverlay) { this.api = api; this.beatmaps = beatmaps; this.notifications = notifications; + this.beatmapSetOverlay = beatmapSetOverlay; AddInternal(content = new Container { @@ -118,6 +120,14 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } + protected override bool OnClick(InputState state) + { + ShowInformation(); + return true; + } + + protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo); + protected void StartDownload() { if (!api.LocalUser.Value.IsSupporter) From f9300ec3fe20138bc133dfee2d88a25773d8e0b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 23:34:56 +0800 Subject: [PATCH 85/96] Populate author using existing data for now --- .../Online/API/Requests/GetBeatmapSetsRequest.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index e4763f73ee..470e13ea7b 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -8,6 +8,7 @@ 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 { @@ -49,6 +50,12 @@ namespace osu.Game.Online.API.Requests [JsonProperty(@"id")] private int onlineId { get; set; } + [JsonProperty(@"creator")] + private string creatorUsername; + + [JsonProperty(@"user_id")] + private long creatorId = 1; + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } @@ -60,6 +67,11 @@ namespace osu.Game.Online.API.Requests Metadata = this, OnlineInfo = new BeatmapSetOnlineInfo { + Author = new User + { + Id = creatorId, + Username = creatorUsername, + }, Covers = covers, Preview = preview, PlayCount = playCount, From f129902ee0ccbce67044105bd6d216c9362195ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 23:35:02 +0800 Subject: [PATCH 86/96] Avoid nullrefs when data is not present --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index d92c8ed509..f1215ab33d 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -40,9 +40,9 @@ namespace osu.Game.Screens.Select.Details firstValue.Value = Beatmap?.Difficulty?.CircleSize ?? 0; } - hpDrain.Value = beatmap.Difficulty.DrainRate; - accuracy.Value = beatmap.Difficulty.OverallDifficulty; - approachRate.Value = beatmap.Difficulty.ApproachRate; + hpDrain.Value = beatmap.Difficulty?.DrainRate ?? 0; + accuracy.Value = beatmap.Difficulty?.OverallDifficulty ?? 0; + approachRate.Value = beatmap.Difficulty?.ApproachRate ?? 0; starDifficulty.Value = (float)beatmap.StarDifficulty; } } From c1081e02b23221409ee2cbe5c04c0b829f904e14 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Sep 2017 23:35:40 +0800 Subject: [PATCH 87/96] Close beatmap overlay on stray mouse clicks --- osu.Game/Overlays/BeatmapSetOverlay.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 6915523975..8e28ad33c5 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions; 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.Containers; @@ -83,6 +84,12 @@ namespace osu.Game.Overlays FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); } + protected override bool OnClick(InputState state) + { + State = Visibility.Hidden; + return true; + } + public void ShowBeatmapSet(BeatmapSetInfo set) { header.BeatmapSet = info.BeatmapSet = set; From 40f597f762d6513a22e94ca3ac9309eae3306fa3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Sep 2017 00:18:35 +0800 Subject: [PATCH 88/96] Add download button to grid view panels --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 9 ++++ osu.Game/Overlays/Direct/DirectListPanel.cs | 44 ----------------- osu.Game/Overlays/Direct/DownloadButton.cs | 53 +++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 63 insertions(+), 44 deletions(-) create mode 100644 osu.Game/Overlays/Direct/DownloadButton.cs diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 0cc1c18d8d..1675a2f663 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -149,6 +149,15 @@ namespace osu.Game.Overlays.Direct }, }, }, + new DownloadButton + { + Size = new Vector2(30), + Margin = new MarginPadding(horizontal_padding), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Colour = colours.Gray5, + Action = StartDownload + }, }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index b3502b0827..6702b7394c 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -11,10 +11,8 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Framework.Input; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Direct { @@ -130,47 +128,5 @@ namespace osu.Game.Overlays.Direct }, }); } - - private class DownloadButton : OsuClickableContainer - { - private readonly SpriteIcon icon; - - public DownloadButton() - { - Children = new Drawable[] - { - icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(30), - Icon = FontAwesome.fa_osu_chevron_down_o, - }, - }; - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - icon.ScaleTo(0.9f, 1000, Easing.Out); - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - icon.ScaleTo(1f, 500, Easing.OutElastic); - return base.OnMouseUp(state, args); - } - - protected override bool OnHover(InputState state) - { - icon.ScaleTo(1.1f, 500, Easing.OutElastic); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - icon.ScaleTo(1f, 500, Easing.OutElastic); - } - } } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs new file mode 100644 index 0000000000..28f5344eae --- /dev/null +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -0,0 +1,53 @@ +// 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.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using OpenTK; + +namespace osu.Game.Overlays.Direct +{ + public class DownloadButton : OsuClickableContainer + { + private readonly SpriteIcon icon; + + public DownloadButton() + { + Children = new Drawable[] + { + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(30), + Icon = FontAwesome.fa_osu_chevron_down_o, + }, + }; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + icon.ScaleTo(0.9f, 1000, Easing.Out); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + icon.ScaleTo(1f, 500, Easing.OutElastic); + return base.OnMouseUp(state, args); + } + + protected override bool OnHover(InputState state) + { + icon.ScaleTo(1.1f, 500, Easing.OutElastic); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + icon.ScaleTo(1f, 500, Easing.OutElastic); + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ddb29c63c3..cd4447c734 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -398,6 +398,7 @@ + From a1f88a17b1afa97d4e02bd85b6670c807d12de99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 15:44:40 +0900 Subject: [PATCH 89/96] Re-namespace and split out timeline parts from the SummaryTimeline --- .../Timelines/Summary/Parts/BookmarkPart.cs | 30 +++++++++ .../Timelines/Summary/Parts/BreakPart.cs | 31 +++++++++ .../Summary/Parts/ControlPointPart.cs | 65 +++++++++++++++++++ .../Timelines/Summary/Parts/TimelinePart.cs | 40 ++++++++++++ .../Visualisations/DurationVisualisation.cs | 25 +++++++ .../Visualisations/PointVisualisation.cs | 24 +++++++ osu.Game/osu.Game.csproj | 6 ++ 7 files changed, 221 insertions(+) create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs new file mode 100644 index 0000000000..5680b85c08 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -0,0 +1,30 @@ +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + /// + /// The part of the timeline that displays bookmarks. + /// + internal class BookmarkPart : TimelinePart + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) + Add(new BookmarkVisualisation(bookmark)); + } + + private class BookmarkVisualisation : PointVisualisation + { + public BookmarkVisualisation(double startTime) + : base(startTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Blue; + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs new file mode 100644 index 0000000000..fefb3d5f10 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -0,0 +1,31 @@ +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + /// + /// The part of the timeline that displays breaks in the song. + /// + internal class BreakPart : TimelinePart + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + foreach (var breakPeriod in beatmap.Beatmap.Breaks) + Add(new BreakVisualisation(breakPeriod)); + } + + private class BreakVisualisation : DurationVisualisation + { + public BreakVisualisation(BreakPeriod breakPeriod) + : base(breakPeriod.StartTime, breakPeriod.EndTime) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Yellow; + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs new file mode 100644 index 0000000000..12b3624123 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -0,0 +1,65 @@ +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + /// + /// The part of the timeline that displays the control points. + /// + internal class ControlPointPart : TimelinePart + { + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; + + cpi.TimingPoints.ForEach(addTimingPoint); + + // Consider all non-timing points as the same type + cpi.SoundPoints.Select(c => (ControlPoint)c) + .Concat(cpi.EffectPoints) + .Concat(cpi.DifficultyPoints) + .Distinct() + // Non-timing points should not be added where there are timing points + .Where(c => cpi.TimingPointAt(c.Time).Time != c.Time) + .ForEach(addNonTimingPoint); + } + + private void addTimingPoint(ControlPoint controlPoint) => Add(new TimingPointVisualisation(controlPoint)); + private void addNonTimingPoint(ControlPoint controlPoint) => Add(new NonTimingPointVisualisation(controlPoint)); + + private class TimingPointVisualisation : ControlPointVisualisation + { + public TimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.YellowDark; + } + + private class NonTimingPointVisualisation : ControlPointVisualisation + { + public NonTimingPointVisualisation(ControlPoint controlPoint) + : base(controlPoint) + { + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Green; + } + + private abstract class ControlPointVisualisation : PointVisualisation + { + protected ControlPointVisualisation(ControlPoint controlPoint) + : base(controlPoint.Time) + { + } + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs new file mode 100644 index 0000000000..30786a80ff --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -0,0 +1,40 @@ +using System; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + /// + /// Represents a part of the summary timeline.. + /// + internal abstract class TimelinePart : CompositeDrawable + { + private readonly Container timeline; + + protected TimelinePart() + { + AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + osuGame.Beatmap.ValueChanged += b => + { + timeline.Clear(); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); + LoadBeatmap(b); + }; + + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); + LoadBeatmap(osuGame.Beatmap); + } + + protected void Add(Drawable visualisation) => timeline.Add(visualisation); + + protected abstract void LoadBeatmap(WorkingBeatmap beatmap); + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs new file mode 100644 index 0000000000..9718e9df5f --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -0,0 +1,25 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations +{ + /// + /// Represents a spanning point on a . + /// + internal class DurationVisualisation : Container + { + protected DurationVisualisation(double startTime, double endTime) + { + Masking = true; + CornerRadius = 5; + + RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.Both; + X = (float)startTime; + Width = (float)(endTime - startTime); + + AddInternal(new Box { RelativeSizeAxes = Axes.Both }); + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs new file mode 100644 index 0000000000..f0eb2ed499 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -0,0 +1,24 @@ +using OpenTK; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations +{ + /// + /// Represents a singular point on a . + /// + internal class PointVisualisation : Box + { + protected PointVisualisation(double startTime) + { + Origin = Anchor.TopCentre; + + RelativeSizeAxes = Axes.Y; + Width = 1; + EdgeSmoothness = new Vector2(1, 0); + + RelativePositionAxes = Axes.X; + X = (float)startTime; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e43f6cfd8c..33eaff8ff5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -606,6 +606,12 @@ + + + + + + From 85cb541fef7898353bf042f1b056afc396a1cbfc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 15:44:59 +0900 Subject: [PATCH 90/96] Implement MarkerPart for the marker --- .../Timelines/Summary/Parts/MarkerPart.cs | 108 ++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 109 insertions(+) create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs new file mode 100644 index 0000000000..9c1587801e --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -0,0 +1,108 @@ +using OpenTK; +using osu.Framework.Allocation; +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; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + /// + /// The part of the timeline that displays the current position of the song. + /// + internal class MarkerPart : TimelinePart + { + private WorkingBeatmap beatmap; + + private readonly Drawable marker; + + public MarkerPart() + { + Add(marker = new MarkerVisualisation()); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + marker.Colour = colours.Red; + } + + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + this.beatmap = beatmap; + } + + protected override bool OnDragStart(InputState state) => true; + protected override bool OnDragEnd(InputState state) => true; + protected override bool OnDrag(InputState state) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + seekToPosition(state.Mouse.NativeState.Position); + return true; + } + + /// + /// Seeks the to the time closest to a position on the screen relative to the . + /// + /// The position in screen coordinates. + private void seekToPosition(Vector2 screenPosition) + { + float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); + seekTo(markerPos / DrawWidth * beatmap.Track.Length); + } + + private void seekTo(double time) => beatmap.Track.Seek(time); + + protected override void Update() + { + base.Update(); + marker.X = (float)beatmap.Track.CurrentTime; + } + + private class MarkerVisualisation : CompositeDrawable + { + public MarkerVisualisation() + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.Centre; + RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + AutoSizeAxes = Axes.X; + InternalChildren = new Drawable[] + { + new Triangle + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Scale = new Vector2(1, -1), + Size = new Vector2(10, 5), + }, + new Triangle + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(10, 5) + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Width = 2, + EdgeSmoothness = new Vector2(1, 0) + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Red; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 33eaff8ff5..0a983bccb0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -609,6 +609,7 @@ + From 5953c1084e023812216a7e4acb8397b401479ae4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 15:45:27 +0900 Subject: [PATCH 91/96] Re-namespace SummaryTimeline --- .../Edit/Components/SummaryTimeline.cs | 357 ------------------ .../Timelines/Summary/SummaryTimeline.cs | 110 ++++++ osu.Game/Screens/Edit/Editor.cs | 2 +- .../Visual/TestCaseEditorSummaryTimeline.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 113 insertions(+), 360 deletions(-) delete mode 100644 osu.Game/Screens/Edit/Components/SummaryTimeline.cs create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs diff --git a/osu.Game/Screens/Edit/Components/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/SummaryTimeline.cs deleted file mode 100644 index 80250eebc3..0000000000 --- a/osu.Game/Screens/Edit/Components/SummaryTimeline.cs +++ /dev/null @@ -1,357 +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.Linq; -using OpenTK; -using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; -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.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Timing; -using osu.Game.Graphics; - -namespace osu.Game.Screens.Edit.Components -{ - /// - /// The timeline that sits at the bottom of the editor. - /// - public class SummaryTimeline : CompositeDrawable - { - private const float corner_radius = 5; - private const float contents_padding = 15; - private const float marker_bar_width = 2; - - private readonly Drawable background; - - private readonly Container markerContainer; - - private readonly Drawable timelineBar; - private readonly Drawable marker; - - private readonly Bindable beatmap = new Bindable(); - - public SummaryTimeline() - { - Masking = true; - CornerRadius = 5; - - InternalChildren = new[] - { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, - Children = new[] - { - markerContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = marker = new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Triangle - { - Anchor = Anchor.TopCentre, - Origin = Anchor.BottomCentre, - Scale = new Vector2(1, -1), - Size = new Vector2(10, 5), - }, - new Triangle - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(10, 5) - }, - new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Y, - Width = 2, - EdgeSmoothness = new Vector2(1, 0) - } - } - } - }, - new ControlPointTimeline - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - new BookmarkTimeline - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - timelineBar = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Size = new Vector2(5) - }, - new Box - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - EdgeSmoothness = new Vector2(0, 1), - }, - new Circle - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Size = new Vector2(5) - }, - } - }, - new BreakTimeline - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.25f - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, OsuColour colours) - { - background.Colour = colours.Gray1; - marker.Colour = colours.Red; - timelineBar.Colour = colours.Gray5; - - beatmap.BindTo(osuGame.Beatmap); - - markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); - beatmap.ValueChanged += b => markerContainer.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); - } - - protected override bool OnDragStart(InputState state) => true; - protected override bool OnDragEnd(InputState state) => true; - protected override bool OnDrag(InputState state) - { - seekToPosition(state.Mouse.NativeState.Position); - return true; - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - seekToPosition(state.Mouse.NativeState.Position); - return true; - } - - /// - /// Seeks the to the time closest to a position on the screen relative to the . - /// - /// The position in screen coordinates. - private void seekToPosition(Vector2 screenPosition) - { - float markerPos = MathHelper.Clamp(markerContainer.ToLocalSpace(screenPosition).X, 0, markerContainer.DrawWidth); - seekTo(markerPos / markerContainer.DrawWidth * beatmap.Value.Track.Length); - } - - private void seekTo(double time) => beatmap.Value.Track.Seek(time); - - protected override void Update() - { - base.Update(); - marker.X = (float)beatmap.Value.Track.CurrentTime; - } - - /// - /// The part of the timeline that displays the control points. - /// - private class ControlPointTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; - - cpi.TimingPoints.ForEach(addTimingPoint); - - // Consider all non-timing points as the same type - cpi.SoundPoints.Select(c => (ControlPoint)c) - .Concat(cpi.EffectPoints) - .Concat(cpi.DifficultyPoints) - .Distinct() - // Non-timing points should not be added where there are timing points - .Where(c => cpi.TimingPointAt(c.Time).Time != c.Time) - .ForEach(addNonTimingPoint); - } - - private void addTimingPoint(ControlPoint controlPoint) => Add(new TimingPointVisualisation(controlPoint)); - private void addNonTimingPoint(ControlPoint controlPoint) => Add(new NonTimingPointVisualisation(controlPoint)); - - private class TimingPointVisualisation : ControlPointVisualisation - { - public TimingPointVisualisation(ControlPoint controlPoint) - : base(controlPoint) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.YellowDark; - } - - private class NonTimingPointVisualisation : ControlPointVisualisation - { - public NonTimingPointVisualisation(ControlPoint controlPoint) - : base(controlPoint) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Green; - } - - private abstract class ControlPointVisualisation : PointVisualisation - { - protected ControlPointVisualisation(ControlPoint controlPoint) - : base(controlPoint.Time) - { - } - } - } - - /// - /// The part of the timeline that displays bookmarks. - /// - private class BookmarkTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) - Add(new BookmarkVisualisation(bookmark)); - } - - private class BookmarkVisualisation : PointVisualisation - { - public BookmarkVisualisation(double startTime) - : base(startTime) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Blue; - } - } - - /// - /// The part of the timeline that displays breaks in the song. - /// - private class BreakTimeline : Timeline - { - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - foreach (var breakPeriod in beatmap.Beatmap.Breaks) - Add(new BreakVisualisation(breakPeriod)); - } - - private class BreakVisualisation : DurationVisualisation - { - public BreakVisualisation(BreakPeriod breakPeriod) - : base(breakPeriod.StartTime, breakPeriod.EndTime) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Yellow; - } - } - - /// - /// Represents a part of the editor timeline. - /// - private abstract class Timeline : CompositeDrawable - { - private readonly Container timeline; - - protected Timeline() - { - AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); - } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - osuGame.Beatmap.ValueChanged += b => - { - timeline.Clear(); - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); - LoadBeatmap(b); - }; - - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); - LoadBeatmap(osuGame.Beatmap); - } - - protected void Add(PointVisualisation visualisation) => timeline.Add(visualisation); - protected void Add(DurationVisualisation visualisation) => timeline.Add(visualisation); - - protected abstract void LoadBeatmap(WorkingBeatmap beatmap); - } - - /// - /// Represents a singular point on a . - /// - private class PointVisualisation : Box - { - protected PointVisualisation(double startTime) - { - Origin = Anchor.TopCentre; - - RelativeSizeAxes = Axes.Y; - Width = 1; - EdgeSmoothness = new Vector2(1, 0); - - RelativePositionAxes = Axes.X; - X = (float)startTime; - } - } - - /// - /// Represents a spanning point on a . - /// - private class DurationVisualisation : Container - { - protected DurationVisualisation(double startTime, double endTime) - { - Masking = true; - CornerRadius = corner_radius; - - RelativePositionAxes = Axes.X; - RelativeSizeAxes = Axes.Both; - X = (float)startTime; - Width = (float)(endTime - startTime); - - AddInternal(new Box { RelativeSizeAxes = Axes.Both }); - } - } - } -} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs new file mode 100644 index 0000000000..31c40861ea --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +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.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary +{ + /// + /// The timeline that sits at the bottom of the editor. + /// + public class SummaryTimeline : CompositeDrawable + { + private const float corner_radius = 5; + private const float contents_padding = 15; + private const float marker_bar_width = 2; + + private readonly Drawable background; + + private readonly Drawable timelineBar; + + public SummaryTimeline() + { + Masking = true; + CornerRadius = corner_radius; + + InternalChildren = new[] + { + background = new Box { RelativeSizeAxes = Axes.Both }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, + Children = new[] + { + new MarkerPart { RelativeSizeAxes = Axes.Both }, + new ControlPointPart + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + new BookmarkPart + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + timelineBar = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Size = new Vector2(5) + }, + new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + EdgeSmoothness = new Vector2(0, 1), + }, + new Circle + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Size = new Vector2(5) + }, + } + }, + new BreakPart + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.25f + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, OsuColour colours) + { + background.Colour = colours.Gray1; + timelineBar.Colour = colours.Gray5; + } + } +} diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index c91ea9d686..7afbbc33bb 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -10,7 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; -using osu.Game.Screens.Edit.Components; +using osu.Game.Screens.Edit.Components.Timelines.Summary; using OpenTK; using osu.Framework.Allocation; diff --git a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index 68c34269f8..59037ce151 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -9,8 +9,8 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Screens.Edit.Components; using OpenTK; +using osu.Game.Screens.Edit.Components.Timelines.Summary; namespace osu.Game.Tests.Visual { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0a983bccb0..d6383ecc22 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -605,7 +605,6 @@ - @@ -613,6 +612,7 @@ + From 10e5fe40b29b75f046383014e8a4f247d051ab50 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 15:51:45 +0900 Subject: [PATCH 92/96] A bit of cleanup --- .../Components/Timelines/Summary/SummaryTimeline.cs | 11 +---------- .../Summary/Visualisations/DurationVisualisation.cs | 2 +- .../Summary/Visualisations/PointVisualisation.cs | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 31c40861ea..0712936bf9 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -1,19 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Linq; using OpenTK; using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; 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.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Timing; using osu.Game.Graphics; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -26,7 +18,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary { private const float corner_radius = 5; private const float contents_padding = 15; - private const float marker_bar_width = 2; private readonly Drawable background; @@ -101,7 +92,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, OsuColour colours) + private void load(OsuColour colours) { background.Colour = colours.Gray1; timelineBar.Colour = colours.Gray5; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs index 9718e9df5f..8926a2f55d 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations { /// - /// Represents a spanning point on a . + /// Represents a spanning point on a timeline part. /// internal class DurationVisualisation : Container { diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index f0eb2ed499..bf52d28d97 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations { /// - /// Represents a singular point on a . + /// Represents a singular point on a timeline part. /// internal class PointVisualisation : Box { From 3937ebdc3dfe642fcac4cfe3e33f6ecc096b0a04 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 15:55:55 +0900 Subject: [PATCH 93/96] Add missing license headers --- .../Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs | 3 +++ .../Edit/Components/Timelines/Summary/Parts/BreakPart.cs | 3 +++ .../Components/Timelines/Summary/Parts/ControlPointPart.cs | 3 +++ .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 3 +++ .../Edit/Components/Timelines/Summary/Parts/TimelinePart.cs | 3 +++ .../Timelines/Summary/Visualisations/DurationVisualisation.cs | 3 +++ .../Timelines/Summary/Visualisations/PointVisualisation.cs | 3 +++ 7 files changed, 21 insertions(+) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs index 5680b85c08..8afec62a08 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -1,3 +1,6 @@ +// 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.Beatmaps; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index fefb3d5f10..721825270b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -1,3 +1,6 @@ +// 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.Beatmaps; using osu.Game.Beatmaps.Timing; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index 12b3624123..e7f4f03f9b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 9c1587801e..d7aa0bcf96 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -1,3 +1,6 @@ +// 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.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 30786a80ff..be3b116711 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -1,3 +1,6 @@ +// 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.Allocation; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs index 8926a2f55d..aee8e250c3 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -1,3 +1,6 @@ +// 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; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index bf52d28d97..9d7272808b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -1,3 +1,6 @@ +// 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.Graphics; using osu.Framework.Graphics.Shapes; From 3b9c2d1d5fe929991f6e2ff1b7371e1e73e1a385 Mon Sep 17 00:00:00 2001 From: Sinnoh <30382015+Xinnoh@users.noreply.github.com> Date: Tue, 26 Sep 2017 16:50:12 +0800 Subject: [PATCH 94/96] changed description for hidden ctb doesn't have approach circles --- osu.Game.Rulesets.Catch/Mods/CatchMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchMod.cs b/osu.Game.Rulesets.Catch/Mods/CatchMod.cs index b0880d7e1d..66261b0f0f 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchMod.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchMod.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Mods public class CatchModHidden : ModHidden { - public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; + public override string Description => @"Play with fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; } From c578509a20d35e730d4edde2f6ddee297dadd98e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 17:56:16 +0900 Subject: [PATCH 95/96] Bind to the screen Beatmap instead of the game-wide Beatmap --- .../Timelines/Summary/Parts/MarkerPart.cs | 62 +++++----- .../Timelines/Summary/Parts/TimelinePart.cs | 17 ++- .../Timelines/Summary/SummaryTimeline.cs | 115 ++++++++++-------- osu.Game/Screens/Edit/Editor.cs | 5 +- .../Visual/TestCaseEditorSummaryTimeline.cs | 34 ++++-- 5 files changed, 125 insertions(+), 108 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index d7aa0bcf96..115aa60446 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -7,7 +7,6 @@ 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; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts @@ -17,8 +16,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// internal class MarkerPart : TimelinePart { - private WorkingBeatmap beatmap; - private readonly Drawable marker; public MarkerPart() @@ -32,11 +29,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts marker.Colour = colours.Red; } - protected override void LoadBeatmap(WorkingBeatmap beatmap) - { - this.beatmap = beatmap; - } - protected override bool OnDragStart(InputState state) => true; protected override bool OnDragEnd(InputState state) => true; protected override bool OnDrag(InputState state) @@ -57,16 +49,22 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// The position in screen coordinates. private void seekToPosition(Vector2 screenPosition) { + if (Beatmap.Value == null) + return; + float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - seekTo(markerPos / DrawWidth * beatmap.Track.Length); + seekTo(markerPos / DrawWidth * Beatmap.Value.Track.Length); } - private void seekTo(double time) => beatmap.Track.Seek(time); + private void seekTo(double time) => Beatmap.Value?.Track.Seek(time); protected override void Update() { base.Update(); - marker.X = (float)beatmap.Track.CurrentTime; + + if (Beatmap.Value == null) + return; + marker.X = (float)Beatmap.Value.Track.CurrentTime; } private class MarkerVisualisation : CompositeDrawable @@ -80,27 +78,27 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts AutoSizeAxes = Axes.X; InternalChildren = new Drawable[] { - new Triangle - { - Anchor = Anchor.TopCentre, - Origin = Anchor.BottomCentre, - Scale = new Vector2(1, -1), - Size = new Vector2(10, 5), - }, - new Triangle - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(10, 5) - }, - new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Y, - Width = 2, - EdgeSmoothness = new Vector2(1, 0) - } + new Triangle + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Scale = new Vector2(1, -1), + Size = new Vector2(10, 5), + }, + new Triangle + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(10, 5) + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Width = 2, + EdgeSmoothness = new Vector2(1, 0) + } }; } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index be3b116711..f5d4124b19 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -3,7 +3,7 @@ using System; using OpenTK; -using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -15,29 +15,26 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// internal abstract class TimelinePart : CompositeDrawable { + public Bindable Beatmap = new Bindable(); + private readonly Container timeline; protected TimelinePart() { AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); - } - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - osuGame.Beatmap.ValueChanged += b => + Beatmap.ValueChanged += b => { timeline.Clear(); timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); LoadBeatmap(b); }; - - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, osuGame.Beatmap.Value.Track.Length), 1); - LoadBeatmap(osuGame.Beatmap); } protected void Add(Drawable visualisation) => timeline.Add(visualisation); - protected abstract void LoadBeatmap(WorkingBeatmap beatmap); + protected virtual void LoadBeatmap(WorkingBeatmap beatmap) + { + } } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 0712936bf9..4d925f7584 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -3,9 +3,11 @@ using OpenTK; using osu.Framework.Allocation; +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; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -19,6 +21,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary private const float corner_radius = 5; private const float contents_padding = 15; + public Bindable Beatmap = new Bindable(); + private readonly Drawable background; private readonly Drawable timelineBar; @@ -28,67 +32,74 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary Masking = true; CornerRadius = corner_radius; + TimelinePart markerPart, controlPointPart, bookmarkPart, breakPart; + InternalChildren = new[] { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Container + background = new Box { RelativeSizeAxes = Axes.Both }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, + Children = new[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, - Children = new[] + markerPart = new MarkerPart { RelativeSizeAxes = Axes.Both }, + controlPointPart = new ControlPointPart { - new MarkerPart { RelativeSizeAxes = Axes.Both }, - new ControlPointPart + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + bookmarkPart = new BookmarkPart + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + timelineBar = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - new BookmarkPart - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f - }, - timelineBar = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + new Circle { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Size = new Vector2(5) - }, - new Box - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - EdgeSmoothness = new Vector2(0, 1), - }, - new Circle - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Size = new Vector2(5) - }, - } - }, - new BreakPart - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.25f + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Size = new Vector2(5) + }, + new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + EdgeSmoothness = new Vector2(0, 1), + }, + new Circle + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Size = new Vector2(5) + }, } + }, + breakPart = new BreakPart + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.25f } } - }; + } + }; + + markerPart.Beatmap.BindTo(Beatmap); + controlPointPart.Beatmap.BindTo(Beatmap); + bookmarkPart.Beatmap.BindTo(Beatmap); + breakPart.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7afbbc33bb..3ffd7754c1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -190,6 +190,7 @@ namespace osu.Game.Screens.Edit } }); + SummaryTimeline summaryTimeline; Add(new Container { Anchor = Anchor.BottomLeft, @@ -211,7 +212,7 @@ namespace osu.Game.Screens.Edit Spacing = new Vector2(10, 0), Children = new[] { - new SummaryTimeline + summaryTimeline = new SummaryTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -223,6 +224,8 @@ namespace osu.Game.Screens.Edit } } }); + + summaryTimeline.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] diff --git a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs index 59037ce151..c35355aefd 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Framework.Graphics; @@ -11,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using OpenTK; using osu.Game.Screens.Edit.Components.Timelines.Summary; +using osu.Framework.Configuration; namespace osu.Game.Tests.Visual { @@ -21,40 +21,48 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(SummaryTimeline) }; + private readonly Bindable beatmap = new Bindable(); + public TestCaseEditorSummaryTimeline() { random = new Random(1337); - Add(new SummaryTimeline + SummaryTimeline summaryTimeline; + Add(summaryTimeline = new SummaryTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(500, 50) }); + + summaryTimeline.Beatmap.BindTo(beatmap); + + AddStep("New beatmap", newBeatmap); + + newBeatmap(); } - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void newBeatmap() { - var beatmap = new Beatmap(); + var b = new Beatmap(); for (int i = 0; i < random.Next(1, 10); i++) - beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { Time = random.Next(0, length) }); + b.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { Time = random.Next(0, length) }); for (int i = 0; i < random.Next(1, 5); i++) - beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint { Time = random.Next(0, length) }); + b.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint { Time = random.Next(0, length) }); for (int i = 0; i < random.Next(1, 5); i++) - beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint { Time = random.Next(0, length) }); + b.ControlPointInfo.EffectPoints.Add(new EffectControlPoint { Time = random.Next(0, length) }); for (int i = 0; i < random.Next(1, 5); i++) - beatmap.ControlPointInfo.SoundPoints.Add(new SoundControlPoint { Time = random.Next(0, length) }); + b.ControlPointInfo.SoundPoints.Add(new SoundControlPoint { Time = random.Next(0, length) }); - beatmap.BeatmapInfo.Bookmarks = new int[random.Next(10, 30)]; - for (int i = 0; i < beatmap.BeatmapInfo.Bookmarks.Length; i++) - beatmap.BeatmapInfo.Bookmarks[i] = random.Next(0, length); + b.BeatmapInfo.Bookmarks = new int[random.Next(10, 30)]; + for (int i = 0; i < b.BeatmapInfo.Bookmarks.Length; i++) + b.BeatmapInfo.Bookmarks[i] = random.Next(0, length); - osuGame.Beatmap.Value = new TestWorkingBeatmap(beatmap); + beatmap.Value = new TestWorkingBeatmap(b); } private class TestWorkingBeatmap : WorkingBeatmap From 10dbd68c1ee89be95c1844d62a8a698ab19c321d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 20:11:45 +0900 Subject: [PATCH 96/96] Simplify null check --- .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 115aa60446..d4a1177c4f 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -62,9 +62,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { base.Update(); - if (Beatmap.Value == null) - return; - marker.X = (float)Beatmap.Value.Track.CurrentTime; + marker.X = (float)(Beatmap.Value?.Track.CurrentTime ?? 0); } private class MarkerVisualisation : CompositeDrawable