From 1d3139d3c3b9c6f0da17e2ebf9b7f688c148b107 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 18:32:07 -0300 Subject: [PATCH 001/291] 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 002/291] 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 003/291] 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 004/291] 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 005/291] 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 006/291] 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 007/291] 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 008/291] 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 009/291] 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 010/291] 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 011/291] 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 012/291] 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 013/291] 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 014/291] 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 015/291] 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 016/291] 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 017/291] 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 018/291] 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 019/291] 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 020/291] 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 021/291] 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 022/291] 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 023/291] 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 024/291] 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 025/291] 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 026/291] 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 027/291] 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 028/291] 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 029/291] 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 030/291] 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 031/291] 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 740e766201ccedccfa191a80a51ebc2c01a62352 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 15 Sep 2017 19:39:55 +0300 Subject: [PATCH 032/291] BreakOverlay and LetterboxOverlay implementation --- .../Visual/TestCaseBreakOverlay.cs | 74 +++++++++++++++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + osu.Game/Beatmaps/Timing/BreakPeriod.cs | 6 +- osu.Game/Screens/Play/BreakOverlay.cs | 64 ++++++++++++++++ osu.Game/Screens/Play/LetterboxOverlay.cs | 63 ++++++++++++++++ osu.Game/Screens/Play/Player.cs | 14 ++-- osu.Game/osu.Game.csproj | 2 + 7 files changed, 216 insertions(+), 8 deletions(-) create mode 100644 osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs create mode 100644 osu.Game/Screens/Play/BreakOverlay.cs create mode 100644 osu.Game/Screens/Play/LetterboxOverlay.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs new file mode 100644 index 0000000000..2c77b1ca39 --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Timing; +using osu.Game.Beatmaps.Timing; +using osu.Game.Screens.Play; +using System.Collections.Generic; + +namespace osu.Desktop.Tests.Visual +{ + internal class TestCaseBreakOverlay : OsuTestCase + { + public override string Description => @"Tests breaks behavior"; + + private readonly BreakOverlay breakOverlay; + + public TestCaseBreakOverlay() + { + Clock = new FramedClock(); + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + breakOverlay = new BreakOverlay(true) + }; + + AddStep("Add 2s break", () => startBreak(2000)); + AddStep("Add 5s break", () => startBreak(5000)); + AddStep("Add 2 breaks (2s each)", startMultipleBreaks); + } + + private void startBreak(double duration) + { + breakOverlay.Breaks = new List + { + new BreakPeriod + { + StartTime = Clock.CurrentTime, + EndTime = Clock.CurrentTime + duration, + } + }; + + breakOverlay.InitializeBreaks(); + } + + private void startMultipleBreaks() + { + double currentTime = Clock.CurrentTime; + + breakOverlay.Breaks = new List + { + new BreakPeriod + { + StartTime = currentTime, + EndTime = currentTime + 2000, + }, + new BreakPeriod + { + StartTime = currentTime + 4000, + EndTime = currentTime + 6000, + } + }; + + breakOverlay.InitializeBreaks(); + } + } +} \ No newline at end of file diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index f894b25f06..5882578b79 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -72,6 +72,7 @@ + diff --git a/osu.Game/Beatmaps/Timing/BreakPeriod.cs b/osu.Game/Beatmaps/Timing/BreakPeriod.cs index fb307b7144..0cf4a0c65b 100644 --- a/osu.Game/Beatmaps/Timing/BreakPeriod.cs +++ b/osu.Game/Beatmaps/Timing/BreakPeriod.cs @@ -8,7 +8,7 @@ namespace osu.Game.Beatmaps.Timing /// /// The minimum duration required for a break to have any effect. /// - private const double min_break_duration = 650; + public const double MIN_BREAK_DURATION = 650; /// /// The break start time. @@ -28,6 +28,6 @@ namespace osu.Game.Beatmaps.Timing /// /// Whether the break has any effect. Breaks that are too short are culled before they are added to the beatmap. /// - public bool HasEffect => Duration >= min_break_duration; + public bool HasEffect => Duration >= MIN_BREAK_DURATION; } -} +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs new file mode 100644 index 0000000000..2cbf6fd3c8 --- /dev/null +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using System.Collections.Generic; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Screens.Play +{ + public class BreakOverlay : VisibilityContainer + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + + public List Breaks; + + private readonly bool letterboxing; + private readonly LetterboxOverlay letterboxOverlay; + + public BreakOverlay(bool letterboxing) + { + this.letterboxing = letterboxing; + + RelativeSizeAxes = Axes.Both; + Child = letterboxOverlay = new LetterboxOverlay(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + InitializeBreaks(); + } + + public void InitializeBreaks() + { + if (Breaks != null) + { + foreach (var b in Breaks) + { + if (b.HasEffect) + { + using (BeginAbsoluteSequence(b.StartTime, true)) + { + Show(); + + using (BeginDelayedSequence(b.Duration, true)) + Hide(); + } + } + } + } + } + + protected override void PopIn() + { + if (letterboxing) letterboxOverlay.FadeIn(fade_duration); + } + + protected override void PopOut() + { + if (letterboxing) letterboxOverlay.FadeOut(fade_duration); + } + } +} diff --git a/osu.Game/Screens/Play/LetterboxOverlay.cs b/osu.Game/Screens/Play/LetterboxOverlay.cs new file mode 100644 index 0000000000..6672b947e7 --- /dev/null +++ b/osu.Game/Screens/Play/LetterboxOverlay.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Screens.Play +{ + public class LetterboxOverlay : Container + { + private const int letterbox_height = 350; + + private Color4 transparentBlack => new Color4(0, 0, 0, 0); + + public LetterboxOverlay() + { + RelativeSizeAxes = Axes.Both; + Alpha = 0; + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + RelativeSizeAxes = Axes.X, + Height = letterbox_height, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = Color4.Black, + TopRight = Color4.Black, + BottomLeft = transparentBlack, + BottomRight = transparentBlack, + } + } + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = letterbox_height, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = transparentBlack, + TopRight = transparentBlack, + BottomLeft = Color4.Black, + BottomRight = Color4.Black, + } + } + } + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 593abb7d26..f7b5da97e9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -161,21 +161,25 @@ namespace osu.Game.Screens.Play }, Children = new Drawable[] { - new SkipButton(firstObjectTime) { AudioClock = decoupledClock }, new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, - Children = new Drawable[] - { - RulesetContainer, - } + Child = RulesetContainer, }, hudOverlay = new HUDOverlay { Anchor = Anchor.Centre, Origin = Anchor.Centre }, + new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Breaks = beatmap.Breaks, + Clock = decoupledClock + }, + new SkipButton(firstObjectTime) { AudioClock = decoupledClock }, } }, failOverlay = new FailOverlay diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 92bcaf90f0..19b32669f5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -81,6 +81,8 @@ + + From 1bac1e2c0e48d5678a92ce6c2152924a01b5b4ce Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 15 Sep 2017 13:47:03 -0300 Subject: [PATCH 033/291] 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 034/291] 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 035/291] 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 036/291] 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 037/291] 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 038/291] 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 039/291] 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 040/291] ... --- 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 041/291] 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 042/291] 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 043/291] 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 be1e868a2a6570a8c33dc7643c89280e13fd2f9c Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sun, 17 Sep 2017 22:39:34 +0200 Subject: [PATCH 044/291] add previews to osu!direct --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 34 +++++++ osu.Game/Overlays/Direct/DirectListPanel.cs | 83 +++++++++++++--- osu.Game/Overlays/Direct/DirectPanel.cs | 7 ++ osu.Game/Overlays/Direct/PlayButton.cs | 105 ++++++++++++++++++++ osu.Game/Overlays/DirectOverlay.cs | 18 ++++ osu.Game/osu.Game.csproj | 1 + 6 files changed, 232 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Overlays/Direct/PlayButton.cs diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 3a9e75bd38..b638e21c4b 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -13,6 +13,8 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Input; +using osu.Framework.Audio; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { @@ -22,6 +24,11 @@ namespace osu.Game.Overlays.Direct private const float vertical_padding = 5; private FillFlowContainer bottomPanel; + private PlayButton playButton; + private Box progressBar; + + protected override PlayButton PlayButton => playButton; + public override Bindable PreviewPlaying { get; } = new Bindable(); public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { @@ -88,6 +95,15 @@ namespace osu.Game.Overlays.Direct { RelativeSizeAxes = Axes.Both, }, + progressBar = new Box + { + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + BypassAutoSizeAxes = Axes.Both, + Size = new Vector2(0, 3), + Alpha = 0, + Colour = colours.Yellow, + }, new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -170,7 +186,25 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, + playButton = new PlayButton(PreviewPlaying) + { + Margin = new MarginPadding { Top = 5, Left = 10 }, + Size = new Vector2(30), + Alpha = 0, + TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + }, }); + + PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && playButton.Track != null) + progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } protected override bool OnClick(InputState state) diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index b3502b0827..7f233f2113 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -15,6 +15,8 @@ using osu.Framework.Input; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Framework.Configuration; +using osu.Framework.Audio; namespace osu.Game.Overlays.Direct { @@ -30,8 +32,14 @@ namespace osu.Game.Overlays.Direct Height = height; } + private PlayButton playButton; + private Box progressBar; + + protected override PlayButton PlayButton => playButton; + public override Bindable PreviewPlaying { get; } = new Bindable(); + [BackgroundDependencyLoader] - private void load(LocalisationEngine localisation) + private void load(LocalisationEngine localisation, OsuColour colours) { Content.CornerRadius = 5; @@ -50,29 +58,51 @@ namespace osu.Game.Overlays.Direct { new FillFlowContainer { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, + Direction = FillDirection.Horizontal, + LayoutEasing = Easing.OutQuint, + LayoutDuration = 120, + Spacing = new Vector2(10, 0), Children = new Drawable[] { - new OsuSpriteText + playButton = new PlayButton(PreviewPlaying) { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), - TextSize = 18, - Font = @"Exo2.0-BoldItalic", - }, - new OsuSpriteText - { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), - Font = @"Exo2.0-BoldItalic", + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Size = new Vector2(height / 2), + FillMode = FillMode.Fit, + Alpha = 0, + TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { - AutoSizeAxes = Axes.X, - Height = 20, - Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, - Children = GetDifficultyIcons(), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), + TextSize = 18, + Font = @"Exo2.0-BoldItalic", + }, + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), + Font = @"Exo2.0-BoldItalic", + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.X, + Height = 20, + Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, + Children = GetDifficultyIcons(), + }, + }, }, - }, + } }, new FillFlowContainer { @@ -128,7 +158,28 @@ namespace osu.Game.Overlays.Direct }, }, }, + progressBar = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + BypassAutoSizeAxes = Axes.Y, + Size = new Vector2(0, 3), + Alpha = 0, + Colour = colours.Yellow, + }, }); + + PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && playButton.Track != null) + progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } private class DownloadButton : OsuClickableContainer diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 6f1f581d0b..24cd8dc54e 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -20,6 +20,7 @@ using osu.Game.Online.API; using osu.Framework.Logging; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { @@ -38,6 +39,9 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; + public abstract Bindable PreviewPlaying { get; } + protected abstract PlayButton PlayButton { get; } + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -106,6 +110,7 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + PlayButton.FadeIn(120, Easing.InOutQuint); return base.OnHover(state); } @@ -114,6 +119,8 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); content.MoveToY(0, hover_transition_time, Easing.OutQuint); + if (!PreviewPlaying) + PlayButton.FadeOut(120, Easing.InOutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs new file mode 100644 index 0000000000..8cfe1a30cb --- /dev/null +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -0,0 +1,105 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using System.Threading.Tasks; + +namespace osu.Game.Overlays.Direct +{ + public class PlayButton : Container + { + public string TrackURL; + + public Bindable Playing; + + public Track Track; + private Bindable gameBeatmap; + private AudioManager audio; + + private Color4 hoverColour; + private readonly SpriteIcon icon; + + public PlayButton(Bindable playing) + { + Playing = playing; + Add(icon = new SpriteIcon() + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.fa_play, + }); + + Playing.ValueChanged += newValue => icon.Icon = newValue ? (Track == null ? FontAwesome.fa_spinner : FontAwesome.fa_pause) : FontAwesome.fa_play; + + Playing.ValueChanged += newValue => + { + if (newValue) + Track?.Start(); + else + Track?.Stop(); + }; + + Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour, OsuGameBase game, AudioManager audio) + { + hoverColour = colour.Yellow; + gameBeatmap = game.Beatmap; + this.audio = audio; + } + + private Task loadTask; + + protected override bool OnClick(InputState state) + { + gameBeatmap.Value.Track.Stop(); + + Playing.Value = !Playing.Value; + + if (loadTask == null) + { + icon.Spin(2000, RotationDirection.Clockwise); + + loadTask = Task.Run(() => + { + Track = audio.Track.Get(TrackURL); + Track.Looping = true; + if (Playing) + Track.Start(); + + icon.ClearTransforms(); + icon.Rotation = 0; + Playing.TriggerChange(); + }); + } + + return true; + } + + protected override bool OnHover(InputState state) + { + icon.FadeColour(hoverColour, 120, Easing.InOutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if(!Playing) + icon.FadeColour(Color4.White, 120, Easing.InOutQuint); + base.OnHoverLost(state); + } + } +} diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9c07e1087f..9bb2afe127 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -32,6 +32,7 @@ namespace osu.Game.Overlays private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; private FillFlowContainer panels; + private DirectPanel playing; protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); @@ -201,6 +202,12 @@ namespace osu.Game.Overlays panels.FadeOut(200); panels.Expire(); panels = null; + + if (playing != null) + { + playing.PreviewPlaying.Value = false; + playing = null; + } } if (BeatmapSets == null) return; @@ -223,6 +230,17 @@ namespace osu.Game.Overlays }) }; + foreach (DirectPanel panel in newPanels.Children) + panel.PreviewPlaying.ValueChanged += newValue => + { + if (newValue) + { + if (playing != null && playing != panel) + playing.PreviewPlaying.Value = false; + playing = panel; + } + }; + LoadComponentAsync(newPanels, p => { if (panels != null) ScrollFlow.Remove(panels); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 65ec7d31b3..f75db14f52 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -105,6 +105,7 @@ + From 3e8ae93b340093b89724ecc34c95e2e0a9676929 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sun, 17 Sep 2017 22:54:23 +0200 Subject: [PATCH 045/291] appveyor --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +-- osu.Game/Overlays/Direct/DirectListPanel.cs | 3 +-- osu.Game/Overlays/Direct/PlayButton.cs | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index b638e21c4b..24ccd8b7eb 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Input; -using osu.Framework.Audio; using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct @@ -191,7 +190,7 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), Alpha = 0, - TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, }); diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7f233f2113..7112e927bd 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -16,7 +16,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Framework.Configuration; -using osu.Framework.Audio; namespace osu.Game.Overlays.Direct { @@ -74,7 +73,7 @@ namespace osu.Game.Overlays.Direct Size = new Vector2(height / 2), FillMode = FillMode.Fit, Alpha = 0, - TrackURL = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", + TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 8cfe1a30cb..b0d011a81c 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - public string TrackURL; + public string TrackUrl; public Bindable Playing; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(Bindable playing) { Playing = playing; - Add(icon = new SpriteIcon() + Add(icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Direct loadTask = Task.Run(() => { - Track = audio.Track.Get(TrackURL); + Track = audio.Track.Get(TrackUrl); Track.Looping = true; if (Playing) Track.Start(); From 10efdffe49f449f3a7e2c522a49c029b73e556a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Sep 2017 15:33:15 +0900 Subject: [PATCH 046/291] 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 047/291] 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 c59d398aa527ae0beeacab2f44351fa9ec8477f6 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 19 Sep 2017 17:26:17 +0300 Subject: [PATCH 048/291] Fix includes --- osu.Game/osu.Game.csproj | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9301002958..5af2e18753 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -277,22 +277,6 @@ - - - - - - - - - - - - - - - - From 85b990c088c0eada760f850ef9706b72ad13def9 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 19 Sep 2017 17:28:10 +0300 Subject: [PATCH 049/291] Remove useless file --- osu.Desktop.Tests/osu.Desktop.Tests.csproj | 179 --------------------- 1 file changed, 179 deletions(-) delete mode 100644 osu.Desktop.Tests/osu.Desktop.Tests.csproj diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj deleted file mode 100644 index 5882578b79..0000000000 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Debug - AnyCPU - {230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D} - Library - Properties - osu.Desktop.Tests - osu.Desktop.Tests - v4.6.1 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - 6 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - True - - - $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll - True - - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll - True - - - False - $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll - - - - $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {65DC628F-A640-4111-AB35-3A5652BC1E17} - osu.Framework.Desktop - - - {007b2356-ab6f-4bd9-96d5-116fc2dce69a} - osu.Framework.Testing - - - {C76BF5B3-985E-4D39-95FE-97C9C879B83A} - osu.Framework - - - {d9a367c9-4c1a-489f-9b05-a0cea2b53b58} - osu.Game.Resources - - - {58F6C80C-1253-4A0E-A465-B8C85EBEADF3} - osu.Game.Rulesets.Catch - - - {48F4582B-7687-4621-9CBE-5C24197CB536} - osu.Game.Rulesets.Mania - - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - - - {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} - osu.Game - - - - - osu.licenseheader - - - - - - - - - - - - - - \ No newline at end of file From 4cf88c72bfece5cfca8dd9b728fd3aa1fd7ffa65 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 19 Sep 2017 17:37:34 +0300 Subject: [PATCH 050/291] Move testcase to the correct project --- .../Tests}/Visual/TestCaseBreakOverlay.cs | 2 +- osu.Game/osu.Game.csproj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename {osu.Desktop.Tests => osu.Game/Tests}/Visual/TestCaseBreakOverlay.cs (95%) diff --git a/osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs similarity index 95% rename from osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs rename to osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 2c77b1ca39..5bf558f79c 100644 --- a/osu.Desktop.Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; using System.Collections.Generic; -namespace osu.Desktop.Tests.Visual +namespace osu.Game.Tests.Visual { internal class TestCaseBreakOverlay : OsuTestCase { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5af2e18753..fef9683cc8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -728,6 +728,7 @@ + From 120446e4a72ddef607693884800d07b01547dfc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 20 Sep 2017 14:31:17 +0900 Subject: [PATCH 051/291] 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 052/291] 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 053/291] 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 054/291] 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 055/291] 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 056/291] 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 057/291] 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 058/291] 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 059/291] 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 060/291] 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 061/291] 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 062/291] 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 063/291] 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 0f04d8c6a7dd2584542eb40e538636e96f0f582a Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 15:58:28 +0300 Subject: [PATCH 064/291] Add remaining time container --- osu.Game/Screens/Play/BreakOverlay.cs | 38 +++++++++++++++---- osu.Game/Tests/Visual/TestCaseBreakOverlay.cs | 10 +---- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 2cbf6fd3c8..5162aa8007 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -5,24 +5,45 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using System.Collections.Generic; using osu.Game.Beatmaps.Timing; +using OpenTK; +using osu.Framework.Graphics.Shapes; +using OpenTK.Graphics; namespace osu.Game.Screens.Play { - public class BreakOverlay : VisibilityContainer + public class BreakOverlay : Container { private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private const int remaining_time_container_max_size = 500; public List Breaks; private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; + private readonly Container remainingTimeContainer; public BreakOverlay(bool letterboxing) { this.letterboxing = letterboxing; RelativeSizeAxes = Axes.Both; - Child = letterboxOverlay = new LetterboxOverlay(); + Children = new Drawable[] + { + letterboxOverlay = new LetterboxOverlay(), + remainingTimeContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0, 8), + CornerRadius = 4, + Masking = true, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + } + } + }; } protected override void LoadComplete() @@ -41,22 +62,25 @@ namespace osu.Game.Screens.Play { using (BeginAbsoluteSequence(b.StartTime, true)) { - Show(); + onBreakIn(b); using (BeginDelayedSequence(b.Duration, true)) - Hide(); + onBreakOut(); } } } } } - protected override void PopIn() + private void onBreakIn(BreakPeriod b) { - if (letterboxing) letterboxOverlay.FadeIn(fade_duration); + if (letterboxing) + letterboxOverlay.FadeIn(fade_duration); + + remainingTimeContainer.ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint).Then().ResizeWidthTo(0, b.Duration); } - protected override void PopOut() + private void onBreakOut() { if (letterboxing) letterboxOverlay.FadeOut(fade_duration); } diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 5bf558f79c..1f59a96de2 100644 --- a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -21,15 +21,7 @@ namespace osu.Game.Tests.Visual { Clock = new FramedClock(); - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, - breakOverlay = new BreakOverlay(true) - }; + Child = breakOverlay = new BreakOverlay(true); AddStep("Add 2s break", () => startBreak(2000)); AddStep("Add 5s break", () => startBreak(5000)); From eb93706c26baec129a0f33d5833e30611ac636aa Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 16:03:31 +0300 Subject: [PATCH 065/291] Remove useless usings --- osu.Game/Tests/Visual/TestCaseBreakOverlay.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 1f59a96de2..2f7a4a2425 100644 --- a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.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 OpenTK.Graphics; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; From 8d7db52200ec08817b46cb70596e5d80f085fd74 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 19:45:38 +0300 Subject: [PATCH 066/291] Add remaining time counter --- osu.Game/Screens/Play/BreakOverlay.cs | 86 +++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 5162aa8007..fe7edf36ff 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -8,6 +8,9 @@ using osu.Game.Beatmaps.Timing; using OpenTK; using osu.Framework.Graphics.Shapes; using OpenTK.Graphics; +using osu.Game.Graphics.Sprites; +using System; +using osu.Framework.Timing; namespace osu.Game.Screens.Play { @@ -18,9 +21,19 @@ namespace osu.Game.Screens.Play public List Breaks; + public override IFrameBasedClock Clock + { + set + { + base.Clock = remainingTimeCounter.Clock = value; + } + get { return base.Clock; } + } + private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; - private readonly Container remainingTimeContainer; + private readonly Container remainingTimeBox; + private readonly RemainingTimeCounter remainingTimeCounter; public BreakOverlay(bool letterboxing) { @@ -30,7 +43,7 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { letterboxOverlay = new LetterboxOverlay(), - remainingTimeContainer = new Container + remainingTimeBox = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -42,6 +55,12 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both, Colour = Color4.White, } + }, + remainingTimeCounter = new RemainingTimeCounter + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Margin = new MarginPadding { Bottom = 25 }, } }; } @@ -77,12 +96,71 @@ namespace osu.Game.Screens.Play if (letterboxing) letterboxOverlay.FadeIn(fade_duration); - remainingTimeContainer.ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint).Then().ResizeWidthTo(0, b.Duration); + remainingTimeBox + .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) + .Then() + .ResizeWidthTo(0, b.Duration); + + Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); + remainingTimeCounter.FadeIn(fade_duration); } private void onBreakOut() { - if (letterboxing) letterboxOverlay.FadeOut(fade_duration); + if (letterboxing) + letterboxOverlay.FadeOut(fade_duration); + + remainingTimeCounter.FadeOut(fade_duration); + } + + private class RemainingTimeCounter : Container + { + private readonly OsuSpriteText counter; + + private int? previousSecond; + + private double remainingTime; + + private bool isCounting; + + public RemainingTimeCounter() + { + AutoSizeAxes = Axes.Both; + Alpha = 0; + Child = counter = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 35, + Font = "Venera", + }; + } + + public void StartCounting(double remainingTime) + { + this.remainingTime = remainingTime; + isCounting = true; + } + + protected override void Update() + { + base.Update(); + + if (isCounting) + { + var currentTime = Clock.CurrentTime; + if (currentTime < remainingTime) + { + int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0) + 1; + if (currentSecond != previousSecond) + { + counter.Text = currentSecond.ToString(); + previousSecond = currentSecond; + } + } + else isCounting = false; + } + } } } } From 4699a4460821d8c318de574b395abf77a35d136e Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 20:50:14 +0300 Subject: [PATCH 067/291] Add info container --- osu.Game/Screens/Play/BreakOverlay.cs | 100 +++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index fe7edf36ff..87dd86b90c 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -11,13 +11,16 @@ using OpenTK.Graphics; using osu.Game.Graphics.Sprites; using System; using osu.Framework.Timing; +using osu.Framework.Allocation; +using osu.Game.Graphics; namespace osu.Game.Screens.Play { public class BreakOverlay : Container { private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; - private const int remaining_time_container_max_size = 500; + private const int remaining_time_container_max_size = 450; + private const int element_margin = 25; public List Breaks; @@ -34,6 +37,7 @@ namespace osu.Game.Screens.Play private readonly LetterboxOverlay letterboxOverlay; private readonly Container remainingTimeBox; private readonly RemainingTimeCounter remainingTimeCounter; + private readonly InfoContainer info; public BreakOverlay(bool letterboxing) { @@ -50,17 +54,19 @@ namespace osu.Game.Screens.Play Size = new Vector2(0, 8), CornerRadius = 4, Masking = true, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - } + Child = new Box { RelativeSizeAxes = Axes.Both } }, remainingTimeCounter = new RemainingTimeCounter { Anchor = Anchor.Centre, Origin = Anchor.BottomCentre, - Margin = new MarginPadding { Bottom = 25 }, + Margin = new MarginPadding { Bottom = element_margin }, + }, + info = new InfoContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding { Top = element_margin }, } }; } @@ -103,6 +109,8 @@ namespace osu.Game.Screens.Play Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); remainingTimeCounter.FadeIn(fade_duration); + + info.FadeIn(fade_duration); } private void onBreakOut() @@ -111,6 +119,82 @@ namespace osu.Game.Screens.Play letterboxOverlay.FadeOut(fade_duration); remainingTimeCounter.FadeOut(fade_duration); + info.FadeOut(fade_duration); + } + + private class InfoContainer : FillFlowContainer + { + public InfoContainer() + { + AutoSizeAxes = Axes.Both; + Alpha = 0; + Direction = FillDirection.Vertical; + Spacing = new Vector2(5); + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"current progress".ToUpper(), + TextSize = 15, + Font = "Exo2.0-Black", + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + Children = new InfoLine[] + { + new InfoLine(@"Accuracy", @"88.54%"), + new InfoLine(@"Rank", @"#6584"), + new InfoLine(@"Grade", @"A"), + }, + } + }; + } + + private class InfoLine : Container + { + private const int margin = 2; + + private readonly OsuSpriteText text; + private readonly OsuSpriteText valueText; + + public InfoLine(string name, string value) + { + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Text = name, + TextSize = 17, + Margin = new MarginPadding { Right = margin } + }, + valueText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Text = value, + TextSize = 17, + Font = "Exo2.0-Bold", + Margin = new MarginPadding { Left = margin } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + text.Colour = colours.Yellow; + valueText.Colour = colours.YellowLight; + } + } } private class RemainingTimeCounter : Container @@ -131,7 +215,7 @@ namespace osu.Game.Screens.Play { Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 35, + TextSize = 33, Font = "Venera", }; } From 581689a84d37ef44d26a91590adb45faf95e71ff Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 20:58:20 +0300 Subject: [PATCH 068/291] CI fixes --- osu.Game/Screens/Play/BreakOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 87dd86b90c..da7ba12a6e 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using osu.Game.Beatmaps.Timing; using OpenTK; using osu.Framework.Graphics.Shapes; -using OpenTK.Graphics; using osu.Game.Graphics.Sprites; using System; using osu.Framework.Timing; @@ -146,7 +145,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Direction = FillDirection.Vertical, - Children = new InfoLine[] + Children = new [] { new InfoLine(@"Accuracy", @"88.54%"), new InfoLine(@"Rank", @"#6584"), From 18a714df74a8e8ef75cf50b8d64a292a269626c1 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 20 Sep 2017 22:33:07 +0300 Subject: [PATCH 069/291] Move every class to it's own file --- osu.Game/Screens/Play/BreakOverlay.cs | 249 ------------------ .../Play/BreaksOverlay/BreakOverlay.cs | 120 +++++++++ .../Play/BreaksOverlay/InfoContainer.cs | 87 ++++++ .../BreaksOverlay/RemainingTimeCounter.cs | 60 +++++ osu.Game/Screens/Play/Player.cs | 1 + osu.Game/Tests/Visual/TestCaseBreakOverlay.cs | 4 +- osu.Game/osu.Game.csproj | 4 +- 7 files changed, 274 insertions(+), 251 deletions(-) delete mode 100644 osu.Game/Screens/Play/BreakOverlay.cs create mode 100644 osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs create mode 100644 osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs create mode 100644 osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs deleted file mode 100644 index da7ba12a6e..0000000000 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics; -using System.Collections.Generic; -using osu.Game.Beatmaps.Timing; -using OpenTK; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Sprites; -using System; -using osu.Framework.Timing; -using osu.Framework.Allocation; -using osu.Game.Graphics; - -namespace osu.Game.Screens.Play -{ - public class BreakOverlay : Container - { - private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; - private const int remaining_time_container_max_size = 450; - private const int element_margin = 25; - - public List Breaks; - - public override IFrameBasedClock Clock - { - set - { - base.Clock = remainingTimeCounter.Clock = value; - } - get { return base.Clock; } - } - - private readonly bool letterboxing; - private readonly LetterboxOverlay letterboxOverlay; - private readonly Container remainingTimeBox; - private readonly RemainingTimeCounter remainingTimeCounter; - private readonly InfoContainer info; - - public BreakOverlay(bool letterboxing) - { - this.letterboxing = letterboxing; - - RelativeSizeAxes = Axes.Both; - Children = new Drawable[] - { - letterboxOverlay = new LetterboxOverlay(), - remainingTimeBox = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(0, 8), - CornerRadius = 4, - Masking = true, - Child = new Box { RelativeSizeAxes = Axes.Both } - }, - remainingTimeCounter = new RemainingTimeCounter - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Margin = new MarginPadding { Bottom = element_margin }, - }, - info = new InfoContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = element_margin }, - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - InitializeBreaks(); - } - - public void InitializeBreaks() - { - if (Breaks != null) - { - foreach (var b in Breaks) - { - if (b.HasEffect) - { - using (BeginAbsoluteSequence(b.StartTime, true)) - { - onBreakIn(b); - - using (BeginDelayedSequence(b.Duration, true)) - onBreakOut(); - } - } - } - } - } - - private void onBreakIn(BreakPeriod b) - { - if (letterboxing) - letterboxOverlay.FadeIn(fade_duration); - - remainingTimeBox - .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) - .Then() - .ResizeWidthTo(0, b.Duration); - - Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); - remainingTimeCounter.FadeIn(fade_duration); - - info.FadeIn(fade_duration); - } - - private void onBreakOut() - { - if (letterboxing) - letterboxOverlay.FadeOut(fade_duration); - - remainingTimeCounter.FadeOut(fade_duration); - info.FadeOut(fade_duration); - } - - private class InfoContainer : FillFlowContainer - { - public InfoContainer() - { - AutoSizeAxes = Axes.Both; - Alpha = 0; - Direction = FillDirection.Vertical; - Spacing = new Vector2(5); - Children = new Drawable[] - { - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = @"current progress".ToUpper(), - TextSize = 15, - Font = "Exo2.0-Black", - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Direction = FillDirection.Vertical, - Children = new [] - { - new InfoLine(@"Accuracy", @"88.54%"), - new InfoLine(@"Rank", @"#6584"), - new InfoLine(@"Grade", @"A"), - }, - } - }; - } - - private class InfoLine : Container - { - private const int margin = 2; - - private readonly OsuSpriteText text; - private readonly OsuSpriteText valueText; - - public InfoLine(string name, string value) - { - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - Text = name, - TextSize = 17, - Margin = new MarginPadding { Right = margin } - }, - valueText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - Text = value, - TextSize = 17, - Font = "Exo2.0-Bold", - Margin = new MarginPadding { Left = margin } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - text.Colour = colours.Yellow; - valueText.Colour = colours.YellowLight; - } - } - } - - private class RemainingTimeCounter : Container - { - private readonly OsuSpriteText counter; - - private int? previousSecond; - - private double remainingTime; - - private bool isCounting; - - public RemainingTimeCounter() - { - AutoSizeAxes = Axes.Both; - Alpha = 0; - Child = counter = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - TextSize = 33, - Font = "Venera", - }; - } - - public void StartCounting(double remainingTime) - { - this.remainingTime = remainingTime; - isCounting = true; - } - - protected override void Update() - { - base.Update(); - - if (isCounting) - { - var currentTime = Clock.CurrentTime; - if (currentTime < remainingTime) - { - int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0) + 1; - if (currentSecond != previousSecond) - { - counter.Text = currentSecond.ToString(); - previousSecond = currentSecond; - } - } - else isCounting = false; - } - } - } - } -} diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs new file mode 100644 index 0000000000..aec96c10ac --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -0,0 +1,120 @@ +// 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.Framework.Graphics.Shapes; +using osu.Framework.Timing; +using osu.Game.Beatmaps.Timing; +using System.Collections.Generic; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class BreakOverlay : Container + { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private const int remaining_time_container_max_size = 450; + private const int element_margin = 25; + + public List Breaks; + + public override IFrameBasedClock Clock + { + set + { + base.Clock = remainingTimeCounter.Clock = value; + } + get { return base.Clock; } + } + + private readonly bool letterboxing; + private readonly LetterboxOverlay letterboxOverlay; + private readonly Container remainingTimeBox; + private readonly RemainingTimeCounter remainingTimeCounter; + private readonly InfoContainer info; + + public BreakOverlay(bool letterboxing) + { + this.letterboxing = letterboxing; + + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + letterboxOverlay = new LetterboxOverlay(), + remainingTimeBox = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0, 8), + CornerRadius = 4, + Masking = true, + Child = new Box { RelativeSizeAxes = Axes.Both } + }, + remainingTimeCounter = new RemainingTimeCounter + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Margin = new MarginPadding { Bottom = element_margin }, + }, + info = new InfoContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding { Top = element_margin }, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + InitializeBreaks(); + } + + public void InitializeBreaks() + { + if (Breaks != null) + { + foreach (var b in Breaks) + { + if (b.HasEffect) + { + using (BeginAbsoluteSequence(b.StartTime, true)) + { + onBreakIn(b); + + using (BeginDelayedSequence(b.Duration, true)) + onBreakOut(); + } + } + } + } + } + + private void onBreakIn(BreakPeriod b) + { + if (letterboxing) + letterboxOverlay.FadeIn(fade_duration); + + remainingTimeBox + .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) + .Then() + .ResizeWidthTo(0, b.Duration); + + Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); + remainingTimeCounter.FadeIn(fade_duration); + + info.FadeIn(fade_duration); + } + + private void onBreakOut() + { + if (letterboxing) + letterboxOverlay.FadeOut(fade_duration); + + remainingTimeCounter.FadeOut(fade_duration); + info.FadeOut(fade_duration); + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs new file mode 100644 index 0000000000..75fcfcba0e --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -0,0 +1,87 @@ +// 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; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class InfoContainer : FillFlowContainer + { + public InfoContainer() + { + AutoSizeAxes = Axes.Both; + Alpha = 0; + Direction = FillDirection.Vertical; + Spacing = new Vector2(5); + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"current progress".ToUpper(), + TextSize = 15, + Font = "Exo2.0-Black", + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + Children = new [] + { + new InfoLine(@"Accuracy", @"-"), + new InfoLine(@"Rank", @"-"), + new InfoLine(@"Grade", @"-"), + }, + } + }; + } + + private class InfoLine : Container + { + private const int margin = 2; + + private readonly OsuSpriteText text; + private readonly OsuSpriteText valueText; + + public InfoLine(string name, string value) + { + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Text = name, + TextSize = 17, + Margin = new MarginPadding { Right = margin } + }, + valueText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Text = value, + TextSize = 17, + Font = "Exo2.0-Bold", + Margin = new MarginPadding { Left = margin } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + text.Colour = colours.Yellow; + valueText.Colour = colours.YellowLight; + } + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs new file mode 100644 index 0000000000..fbf3e10688 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics; +using System; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class RemainingTimeCounter : Container + { + private readonly OsuSpriteText counter; + + private int? previousSecond; + + private double remainingTime; + + private bool isCounting; + + public RemainingTimeCounter() + { + AutoSizeAxes = Axes.Both; + Alpha = 0; + Child = counter = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 33, + Font = "Venera", + }; + } + + public void StartCounting(double remainingTime) + { + this.remainingTime = remainingTime; + isCounting = true; + } + + protected override void Update() + { + base.Update(); + + if (isCounting) + { + var currentTime = Clock.CurrentTime; + if (currentTime < remainingTime) + { + int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0) + 1; + if (currentSecond != previousSecond) + { + counter.Text = currentSecond.ToString(); + previousSecond = currentSecond; + } + } + else isCounting = false; + } + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f7b5da97e9..86aa00875c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Screens.Play.BreaksOverlay; namespace osu.Game.Screens.Play { diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 2f7a4a2425..055a2bc5c4 100644 --- a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -3,7 +3,7 @@ using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; -using osu.Game.Screens.Play; +using osu.Game.Screens.Play.BreaksOverlay; using System.Collections.Generic; namespace osu.Game.Tests.Visual @@ -22,6 +22,8 @@ namespace osu.Game.Tests.Visual AddStep("Add 2s break", () => startBreak(2000)); AddStep("Add 5s break", () => startBreak(5000)); + AddStep("Add 10s break", () => startBreak(10000)); + AddStep("Add 15s break", () => startBreak(15000)); AddStep("Add 2 breaks (2s each)", startMultipleBreaks); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fef9683cc8..406867c656 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,7 +275,9 @@ - + + + From c79568135a44d1889c6a2f204bf6f12589049427 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 21 Sep 2017 01:44:30 +0300 Subject: [PATCH 070/291] Add arrows --- .../Screens/Play/BreaksOverlay/BlurredIcon.cs | 40 ++++++++++ .../Play/BreaksOverlay/BreakOverlay.cs | 60 +++++++++++++-- .../Screens/Play/BreaksOverlay/GlowingIcon.cs | 74 +++++++++++++++++++ .../{ => BreaksOverlay}/LetterboxOverlay.cs | 4 +- osu.Game/osu.Game.csproj | 4 +- 5 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs create mode 100644 osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs rename osu.Game/Screens/Play/{ => BreaksOverlay}/LetterboxOverlay.cs (95%) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs new file mode 100644 index 0000000000..582bd818bd --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs @@ -0,0 +1,40 @@ +// 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.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class BlurredIcon : BufferedContainer + { + private const int icon_size = 130; + + private readonly GlowingIcon icon; + + public FontAwesome Icon + { + set { icon.Icon = value; } + get { return icon.Icon; } + } + + public BlurredIcon() + { + Anchor = Anchor.CentreLeft; + RelativePositionAxes = Axes.X; + Size = new Vector2(icon_size * 1.7f); + Masking = true; + BlurSigma = new Vector2(20); + Alpha = 0.6f; + CacheDrawnFrameBuffer = true; + Child = icon = new GlowingIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Size = new Vector2(icon_size), + }; + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index aec96c10ac..7e245a33d9 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -14,8 +14,11 @@ namespace osu.Game.Screens.Play.BreaksOverlay public class BreakOverlay : Container { private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; - private const int remaining_time_container_max_size = 450; - private const int element_margin = 25; + private const float remaining_time_container_max_size = 0.35f; + private const int vertical_margin = 25; + private const float glowing_x_offset = 0.13f; + private const float glowing_x_final = 0.22f; + private const float blurred_x_offset = 0.2f; public List Breaks; @@ -34,6 +37,12 @@ namespace osu.Game.Screens.Play.BreaksOverlay private readonly RemainingTimeCounter remainingTimeCounter; private readonly InfoContainer info; + private readonly GlowingIcon leftGlowingIcon; + private readonly GlowingIcon rightGlowingIcon; + + private readonly BlurredIcon leftBlurredIcon; + private readonly BlurredIcon rightBlurredIcon; + public BreakOverlay(bool letterboxing) { this.letterboxing = letterboxing; @@ -41,11 +50,16 @@ namespace osu.Game.Screens.Play.BreaksOverlay RelativeSizeAxes = Axes.Both; Children = new Drawable[] { - letterboxOverlay = new LetterboxOverlay(), + letterboxOverlay = new LetterboxOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, remainingTimeBox = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, Size = new Vector2(0, 8), CornerRadius = 4, Masking = true, @@ -55,13 +69,35 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.BottomCentre, - Margin = new MarginPadding { Bottom = element_margin }, + Margin = new MarginPadding { Bottom = vertical_margin }, }, info = new InfoContainer { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = element_margin }, + Margin = new MarginPadding { Top = vertical_margin }, + }, + leftGlowingIcon = new GlowingIcon + { + Origin = Anchor.CentreRight, + Icon = Graphics.FontAwesome.fa_chevron_left, + Size = new Vector2(60), + }, + rightGlowingIcon = new GlowingIcon + { + Origin = Anchor.CentreLeft, + Icon = Graphics.FontAwesome.fa_chevron_right, + Size = new Vector2(60), + }, + leftBlurredIcon = new BlurredIcon + { + Origin = Anchor.CentreRight, + Icon = Graphics.FontAwesome.fa_chevron_left, + }, + rightBlurredIcon = new BlurredIcon + { + Origin = Anchor.CentreLeft, + Icon = Graphics.FontAwesome.fa_chevron_right, } }; } @@ -102,10 +138,16 @@ namespace osu.Game.Screens.Play.BreaksOverlay .Then() .ResizeWidthTo(0, b.Duration); - Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); + Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime); remainingTimeCounter.FadeIn(fade_duration); info.FadeIn(fade_duration); + + leftGlowingIcon.MoveToX(1 - glowing_x_final, fade_duration, Easing.OutQuint); + rightGlowingIcon.MoveToX(glowing_x_final, fade_duration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(1, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(0, fade_duration, Easing.OutQuint); } private void onBreakOut() @@ -115,6 +157,12 @@ namespace osu.Game.Screens.Play.BreaksOverlay remainingTimeCounter.FadeOut(fade_duration); info.FadeOut(fade_duration); + + leftGlowingIcon.MoveToX(1 + glowing_x_offset, fade_duration, Easing.OutQuint); + rightGlowingIcon.MoveToX(-glowing_x_offset, fade_duration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(1 + blurred_x_offset, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(-blurred_x_offset, fade_duration, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs new file mode 100644 index 0000000000..fe08a81c5a --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs @@ -0,0 +1,74 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class GlowingIcon : Container + { + private readonly SpriteIcon icon; + private readonly SpriteIcon glow; + private readonly BufferedContainer glowContainer; + + public FontAwesome Icon + { + set { icon.Icon = glow.Icon = value; } + get { return icon.Icon; } + } + + public override Vector2 Size + { + set + { + glow.Size = icon.Size = value; + glowContainer.Size = value * 1.5f; + } + get + { + return glow.Size; + } + } + + public GlowingIcon() + { + Anchor = Anchor.CentreLeft; + RelativePositionAxes = Axes.X; + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + glowContainer = new BufferedContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + BlurSigma = new Vector2(10), + CacheDrawnFrameBuffer = true, + Child = glow = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Shadow = false, + }, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Shadow = false, + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + glow.Colour = colours.Blue; + } + } +} diff --git a/osu.Game/Screens/Play/LetterboxOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs similarity index 95% rename from osu.Game/Screens/Play/LetterboxOverlay.cs rename to osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs index 6672b947e7..c95b15ef3a 100644 --- a/osu.Game/Screens/Play/LetterboxOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.BreaksOverlay { public class LetterboxOverlay : Container { @@ -60,4 +60,4 @@ namespace osu.Game.Screens.Play }; } } -} \ No newline at end of file +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 406867c656..904e7800b8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,10 +275,12 @@ + + + - From e051bcc6dfd1895bbbca61dac269a5e59e1cf2bd Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 21 Sep 2017 01:51:40 +0300 Subject: [PATCH 071/291] Fix wrong arrows position on startup --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 7e245a33d9..d603298262 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -82,22 +82,26 @@ namespace osu.Game.Screens.Play.BreaksOverlay Origin = Anchor.CentreRight, Icon = Graphics.FontAwesome.fa_chevron_left, Size = new Vector2(60), + X = 1 + glowing_x_offset, }, rightGlowingIcon = new GlowingIcon { Origin = Anchor.CentreLeft, Icon = Graphics.FontAwesome.fa_chevron_right, Size = new Vector2(60), + X = -glowing_x_offset, }, leftBlurredIcon = new BlurredIcon { Origin = Anchor.CentreRight, Icon = Graphics.FontAwesome.fa_chevron_left, + X = 1 + blurred_x_offset, }, rightBlurredIcon = new BlurredIcon { Origin = Anchor.CentreLeft, Icon = Graphics.FontAwesome.fa_chevron_right, + X = -blurred_x_offset, } }; } From 9667270336263be0894280dd0becb12186b4e602 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 21 Sep 2017 01:56:50 +0300 Subject: [PATCH 072/291] Remove using --- osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs index fe08a81c5a..c92b0121c9 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs @@ -2,7 +2,6 @@ // 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.Graphics; using osu.Framework.Graphics.Containers; From 46af17f00c4b98b66ba0efaa647085c132abf9a4 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 21 Sep 2017 14:46:51 -0300 Subject: [PATCH 073/291] 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 074/291] 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 22ab2c5e5dfd6e26e5050e2a220a23072c451224 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 21 Sep 2017 22:54:46 +0300 Subject: [PATCH 075/291] Apply suggested changes --- .../Play/BreaksOverlay/BreakOverlay.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index d603298262..970e8c7d49 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -114,20 +114,20 @@ namespace osu.Game.Screens.Play.BreaksOverlay public void InitializeBreaks() { - if (Breaks != null) - { - foreach (var b in Breaks) - { - if (b.HasEffect) - { - using (BeginAbsoluteSequence(b.StartTime, true)) - { - onBreakIn(b); + if (Breaks == null) + return; - using (BeginDelayedSequence(b.Duration, true)) - onBreakOut(); - } - } + foreach (var b in Breaks) + { + if (!b.HasEffect) + continue; + + using (BeginAbsoluteSequence(b.StartTime, true)) + { + onBreakIn(b); + + using (BeginDelayedSequence(b.Duration, true)) + onBreakOut(); } } } From 5383e33f3d5616431fa03ebed2598e60a0317f8e Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 21 Sep 2017 22:58:49 +0300 Subject: [PATCH 076/291] Remove useless clock assignment --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 970e8c7d49..29b24f1f87 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -5,7 +5,6 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using System.Collections.Generic; @@ -22,15 +21,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay public List Breaks; - public override IFrameBasedClock Clock - { - set - { - base.Clock = remainingTimeCounter.Clock = value; - } - get { return base.Clock; } - } - private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; private readonly Container remainingTimeBox; From 8438ea1267c28a2e86b210d099fb8a83dc904c6f Mon Sep 17 00:00:00 2001 From: gabixdev Date: Thu, 21 Sep 2017 22:11:35 +0200 Subject: [PATCH 077/291] 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 56bde648393fb8870d1d755d9b531d972c862a82 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 01:16:05 +0300 Subject: [PATCH 078/291] Add arrows overlay --- .../Play/BreaksOverlay/ArrowsOverlay.cs | 84 +++++++++++++++++++ .../Screens/Play/BreaksOverlay/BlurredIcon.cs | 22 +++-- .../Play/BreaksOverlay/BreakOverlay.cs | 51 ++--------- .../{GlowingIcon.cs => GlowIcon.cs} | 48 +++++------ osu.Game/osu.Game.csproj | 3 +- 5 files changed, 129 insertions(+), 79 deletions(-) create mode 100644 osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs rename osu.Game/Screens/Play/BreaksOverlay/{GlowingIcon.cs => GlowIcon.cs} (65%) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs new file mode 100644 index 0000000000..715cc4fc0f --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using OpenTK; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class ArrowsOverlay : Container + { + private const int glowing_size = 60; + private const float glowing_final_offset = 0.25f; + private const float glowing_offscreen_offset = 0.6f; + + private const int blurred_size = 130; + private const float blurred_final_offset = 0.35f; + private const float blurred_offscreen_offset = 0.7f; + + private readonly GlowIcon leftGlowIcon; + private readonly GlowIcon rightGlowIcon; + + private readonly BlurredIcon leftBlurredIcon; + private readonly BlurredIcon rightBlurredIcon; + + public ArrowsOverlay() + { + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + leftGlowIcon = new GlowIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + X = - glowing_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_right, + Size = new Vector2(glowing_size), + }, + rightGlowIcon = new GlowIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + X = glowing_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_left, + Size = new Vector2(glowing_size), + }, + leftBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + X = - blurred_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_right, + Size = new Vector2(blurred_size), + }, + rightBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + X = blurred_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_left, + Size = new Vector2(blurred_size), + }, + }; + } + + public void Show(double fadeDuration) + { + leftGlowIcon.MoveToX(-glowing_final_offset, fadeDuration, Easing.OutQuint); + rightGlowIcon.MoveToX(glowing_final_offset, fadeDuration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(-blurred_final_offset, fadeDuration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_final_offset, fadeDuration, Easing.OutQuint); + } + + public void Hide(double fadeDuration) + { + leftGlowIcon.MoveToX(-glowing_offscreen_offset, fadeDuration, Easing.OutQuint); + rightGlowIcon.MoveToX(glowing_offscreen_offset, fadeDuration, Easing.OutQuint); + + leftBlurredIcon.MoveToX(-blurred_offscreen_offset, fadeDuration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_offscreen_offset, fadeDuration, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs index 582bd818bd..25e6eef1fd 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs @@ -10,9 +10,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public class BlurredIcon : BufferedContainer { - private const int icon_size = 130; + private const int blur_sigma = 20; - private readonly GlowingIcon icon; + private readonly GlowIcon icon; public FontAwesome Icon { @@ -20,20 +20,26 @@ namespace osu.Game.Screens.Play.BreaksOverlay get { return icon.Icon; } } + public override Vector2 Size + { + set + { + icon.Size = value; + base.Size = value + new Vector2(blur_sigma * 2); + } + get { return icon.Size; } + } + public BlurredIcon() { - Anchor = Anchor.CentreLeft; RelativePositionAxes = Axes.X; - Size = new Vector2(icon_size * 1.7f); - Masking = true; - BlurSigma = new Vector2(20); + BlurSigma = new Vector2(blur_sigma); Alpha = 0.6f; CacheDrawnFrameBuffer = true; - Child = icon = new GlowingIcon + Child = icon = new GlowIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Size = new Vector2(icon_size), }; } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 29b24f1f87..c0088ce816 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -15,9 +15,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; private const float remaining_time_container_max_size = 0.35f; private const int vertical_margin = 25; - private const float glowing_x_offset = 0.13f; - private const float glowing_x_final = 0.22f; - private const float blurred_x_offset = 0.2f; public List Breaks; @@ -26,12 +23,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay private readonly Container remainingTimeBox; private readonly RemainingTimeCounter remainingTimeCounter; private readonly InfoContainer info; - - private readonly GlowingIcon leftGlowingIcon; - private readonly GlowingIcon rightGlowingIcon; - - private readonly BlurredIcon leftBlurredIcon; - private readonly BlurredIcon rightBlurredIcon; + private readonly ArrowsOverlay arrowsOverlay; public BreakOverlay(bool letterboxing) { @@ -67,31 +59,10 @@ namespace osu.Game.Screens.Play.BreaksOverlay Origin = Anchor.TopCentre, Margin = new MarginPadding { Top = vertical_margin }, }, - leftGlowingIcon = new GlowingIcon + arrowsOverlay = new ArrowsOverlay { - Origin = Anchor.CentreRight, - Icon = Graphics.FontAwesome.fa_chevron_left, - Size = new Vector2(60), - X = 1 + glowing_x_offset, - }, - rightGlowingIcon = new GlowingIcon - { - Origin = Anchor.CentreLeft, - Icon = Graphics.FontAwesome.fa_chevron_right, - Size = new Vector2(60), - X = -glowing_x_offset, - }, - leftBlurredIcon = new BlurredIcon - { - Origin = Anchor.CentreRight, - Icon = Graphics.FontAwesome.fa_chevron_left, - X = 1 + blurred_x_offset, - }, - rightBlurredIcon = new BlurredIcon - { - Origin = Anchor.CentreLeft, - Icon = Graphics.FontAwesome.fa_chevron_right, - X = -blurred_x_offset, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, } }; } @@ -136,12 +107,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay remainingTimeCounter.FadeIn(fade_duration); info.FadeIn(fade_duration); - - leftGlowingIcon.MoveToX(1 - glowing_x_final, fade_duration, Easing.OutQuint); - rightGlowingIcon.MoveToX(glowing_x_final, fade_duration, Easing.OutQuint); - - leftBlurredIcon.MoveToX(1, fade_duration, Easing.OutQuint); - rightBlurredIcon.MoveToX(0, fade_duration, Easing.OutQuint); + arrowsOverlay.Show(fade_duration); } private void onBreakOut() @@ -151,12 +117,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay remainingTimeCounter.FadeOut(fade_duration); info.FadeOut(fade_duration); - - leftGlowingIcon.MoveToX(1 + glowing_x_offset, fade_duration, Easing.OutQuint); - rightGlowingIcon.MoveToX(-glowing_x_offset, fade_duration, Easing.OutQuint); - - leftBlurredIcon.MoveToX(1 + blurred_x_offset, fade_duration, Easing.OutQuint); - rightBlurredIcon.MoveToX(-blurred_x_offset, fade_duration, Easing.OutQuint); + arrowsOverlay.Hide(fade_duration); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs similarity index 65% rename from osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs rename to osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs index c92b0121c9..91e794ff6b 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/GlowingIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs @@ -1,42 +1,40 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; using OpenTK; using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; namespace osu.Game.Screens.Play.BreaksOverlay { - public class GlowingIcon : Container + public class GlowIcon : Container { - private readonly SpriteIcon icon; - private readonly SpriteIcon glow; - private readonly BufferedContainer glowContainer; + private const int blur_sigma = 5; - public FontAwesome Icon - { - set { icon.Icon = glow.Icon = value; } - get { return icon.Icon; } - } + private readonly SpriteIcon spriteIcon; + private readonly SpriteIcon glowIcon; + private readonly BufferedContainer glowContainer; public override Vector2 Size { set { - glow.Size = icon.Size = value; - glowContainer.Size = value * 1.5f; - } - get - { - return glow.Size; + spriteIcon.Size = glowIcon.Size = value; + glowContainer.Size = value + new Vector2(blur_sigma * 2); } + get { return spriteIcon.Size; } } - public GlowingIcon() + public FontAwesome Icon + { + set { spriteIcon.Icon = glowIcon.Icon = value; } + get { return spriteIcon.Icon; } + } + + public GlowIcon() { - Anchor = Anchor.CentreLeft; RelativePositionAxes = Axes.X; AutoSizeAxes = Axes.Both; Children = new Drawable[] @@ -45,17 +43,17 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Masking = true, - BlurSigma = new Vector2(10), + BlurSigma = new Vector2(blur_sigma), CacheDrawnFrameBuffer = true, - Child = glow = new SpriteIcon + Child = glowIcon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Shadow = false, }, + }, - icon = new SpriteIcon + spriteIcon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -67,7 +65,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay [BackgroundDependencyLoader] private void load(OsuColour colours) { - glow.Colour = colours.Blue; + glowIcon.Colour = colours.BlueLight; } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 904e7800b8..dd823f6144 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,9 +275,10 @@ + - + From 31e26364a6c5dda84e294ff60e88820ef7c9d69f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 01:47:24 +0200 Subject: [PATCH 079/291] 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 080/291] 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 081/291] 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 082/291] 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 083/291] 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 084/291] 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 085/291] 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 086/291] 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 087/291] 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 d58e5a613015beb9ffb9e1da672ab2bcdaf5db7d Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 20:43:51 +0300 Subject: [PATCH 088/291] Arrows improvements --- .../Play/BreaksOverlay/ArrowsOverlay.cs | 50 +++++++++++-------- .../Screens/Play/BreaksOverlay/BlurredIcon.cs | 22 +++++--- .../Play/BreaksOverlay/BreakOverlay.cs | 2 +- .../Screens/Play/BreaksOverlay/GlowIcon.cs | 33 ++++++------ 4 files changed, 57 insertions(+), 50 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 715cc4fc0f..8ba801f204 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -9,13 +9,15 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public class ArrowsOverlay : Container { - private const int glowing_size = 60; - private const float glowing_final_offset = 0.25f; - private const float glowing_offscreen_offset = 0.6f; + private const int glow_icon_size = 65; + private const int glow_icon_blur_sigma = 8; + private const float glow_icon_final_offset = 0.2f; + private const float glow_icon_offscreen_offset = 0.6f; - private const int blurred_size = 130; - private const float blurred_final_offset = 0.35f; - private const float blurred_offscreen_offset = 0.7f; + private const int blurred_icon_blur_sigma = 20; + private const int blurred_icon_size = 130; + private const float blurred_icon_final_offset = 0.35f; + private const float blurred_icon_offscreen_offset = 0.7f; private readonly GlowIcon leftGlowIcon; private readonly GlowIcon rightGlowIcon; @@ -32,53 +34,57 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, - X = - glowing_offscreen_offset, + X = - glow_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_right, - Size = new Vector2(glowing_size), + BlurSigma = new Vector2(glow_icon_blur_sigma), + Size = new Vector2(glow_icon_size), }, rightGlowIcon = new GlowIcon { Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, - X = glowing_offscreen_offset, + X = glow_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_left, - Size = new Vector2(glowing_size), + BlurSigma = new Vector2(glow_icon_blur_sigma), + Size = new Vector2(glow_icon_size), }, leftBlurredIcon = new BlurredIcon { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, - X = - blurred_offscreen_offset, + X = - blurred_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_right, - Size = new Vector2(blurred_size), + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), }, rightBlurredIcon = new BlurredIcon { Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, - X = blurred_offscreen_offset, + X = blurred_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_left, - Size = new Vector2(blurred_size), + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), }, }; } public void Show(double fadeDuration) { - leftGlowIcon.MoveToX(-glowing_final_offset, fadeDuration, Easing.OutQuint); - rightGlowIcon.MoveToX(glowing_final_offset, fadeDuration, Easing.OutQuint); + leftGlowIcon.MoveToX(-glow_icon_final_offset, fadeDuration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_final_offset, fadeDuration, Easing.OutQuint); - leftBlurredIcon.MoveToX(-blurred_final_offset, fadeDuration, Easing.OutQuint); - rightBlurredIcon.MoveToX(blurred_final_offset, fadeDuration, Easing.OutQuint); + leftBlurredIcon.MoveToX(-blurred_icon_final_offset, fadeDuration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_final_offset, fadeDuration, Easing.OutQuint); } public void Hide(double fadeDuration) { - leftGlowIcon.MoveToX(-glowing_offscreen_offset, fadeDuration, Easing.OutQuint); - rightGlowIcon.MoveToX(glowing_offscreen_offset, fadeDuration, Easing.OutQuint); + leftGlowIcon.MoveToX(-glow_icon_offscreen_offset, fadeDuration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_offscreen_offset, fadeDuration, Easing.OutQuint); - leftBlurredIcon.MoveToX(-blurred_offscreen_offset, fadeDuration, Easing.OutQuint); - rightBlurredIcon.MoveToX(blurred_offscreen_offset, fadeDuration, Easing.OutQuint); + leftBlurredIcon.MoveToX(-blurred_icon_offscreen_offset, fadeDuration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_offscreen_offset, fadeDuration, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs index 25e6eef1fd..9e69d9d076 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs @@ -5,14 +5,13 @@ using OpenTK; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Framework.Allocation; namespace osu.Game.Screens.Play.BreaksOverlay { public class BlurredIcon : BufferedContainer { - private const int blur_sigma = 20; - - private readonly GlowIcon icon; + private readonly SpriteIcon icon; public FontAwesome Icon { @@ -25,22 +24,29 @@ namespace osu.Game.Screens.Play.BreaksOverlay set { icon.Size = value; - base.Size = value + new Vector2(blur_sigma * 2); + base.Size = value + BlurSigma * 2.5f; + ForceRedraw(); } - get { return icon.Size; } + get { return base.Size; } } public BlurredIcon() { RelativePositionAxes = Axes.X; - BlurSigma = new Vector2(blur_sigma); - Alpha = 0.6f; + Alpha = 0.7f; CacheDrawnFrameBuffer = true; - Child = icon = new GlowIcon + Child = icon = new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, + Shadow = false, }; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Colour = colours.BlueLighter; + } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index c0088ce816..1264feff3d 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay public class BreakOverlay : Container { private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; - private const float remaining_time_container_max_size = 0.35f; + private const float remaining_time_container_max_size = 0.3f; private const int vertical_margin = 25; public List Breaks; diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs index 91e794ff6b..81c2445324 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs @@ -11,25 +11,29 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public class GlowIcon : Container { - private const int blur_sigma = 5; - private readonly SpriteIcon spriteIcon; - private readonly SpriteIcon glowIcon; - private readonly BufferedContainer glowContainer; + private readonly BlurredIcon blurredIcon; public override Vector2 Size { set { - spriteIcon.Size = glowIcon.Size = value; - glowContainer.Size = value + new Vector2(blur_sigma * 2); + blurredIcon.Size = value; + spriteIcon.Size = value - new Vector2(10); //Make it a bit smaller to make blur more visible + blurredIcon.ForceRedraw(); } - get { return spriteIcon.Size; } + get { return base.Size; } + } + + public Vector2 BlurSigma + { + set { blurredIcon.BlurSigma = value; } + get { return blurredIcon.BlurSigma; } } public FontAwesome Icon { - set { spriteIcon.Icon = glowIcon.Icon = value; } + set { spriteIcon.Icon = blurredIcon.Icon = value; } get { return spriteIcon.Icon; } } @@ -39,19 +43,10 @@ namespace osu.Game.Screens.Play.BreaksOverlay AutoSizeAxes = Axes.Both; Children = new Drawable[] { - glowContainer = new BufferedContainer + blurredIcon = new BlurredIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - BlurSigma = new Vector2(blur_sigma), - CacheDrawnFrameBuffer = true, - Child = glowIcon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Shadow = false, - }, - }, spriteIcon = new SpriteIcon { @@ -65,7 +60,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay [BackgroundDependencyLoader] private void load(OsuColour colours) { - glowIcon.Colour = colours.BlueLight; + blurredIcon.Colour = colours.Blue; } } } From 6fe2b64abdc0a7ab551e79e557932851e54cacab Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 20:50:00 +0300 Subject: [PATCH 089/291] Start breakOut animation a bit earlier --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 1264feff3d..27b7dc5408 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { onBreakIn(b); - using (BeginDelayedSequence(b.Duration, true)) + using (BeginDelayedSequence(b.Duration - fade_duration, true)) onBreakOut(); } } From 92eb8e4fa9700640ab322a0e8d850ae37255c5a0 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 21:00:45 +0300 Subject: [PATCH 090/291] Move blurred icons to a parallax container --- .../Play/BreaksOverlay/ArrowsOverlay.cs | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 8ba801f204..9178daac54 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using OpenTK; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -48,24 +49,31 @@ namespace osu.Game.Screens.Play.BreaksOverlay BlurSigma = new Vector2(glow_icon_blur_sigma), Size = new Vector2(glow_icon_size), }, - leftBlurredIcon = new BlurredIcon + new ParallaxContainer { - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - X = - blurred_icon_offscreen_offset, - Icon = Graphics.FontAwesome.fa_chevron_right, - BlurSigma = new Vector2(blurred_icon_blur_sigma), - Size = new Vector2(blurred_icon_size), - }, - rightBlurredIcon = new BlurredIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - X = blurred_icon_offscreen_offset, - Icon = Graphics.FontAwesome.fa_chevron_left, - BlurSigma = new Vector2(blurred_icon_blur_sigma), - Size = new Vector2(blurred_icon_size), - }, + ParallaxAmount = -0.02f, + Children = new Drawable[] + { + leftBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + X = - blurred_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_right, + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), + }, + rightBlurredIcon = new BlurredIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + X = blurred_icon_offscreen_offset, + Icon = Graphics.FontAwesome.fa_chevron_left, + BlurSigma = new Vector2(blurred_icon_blur_sigma), + Size = new Vector2(blurred_icon_size), + }, + } + } }; } From d73b40768e50426ed44349da7a6ad8d5f13fb143 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 21:12:58 +0300 Subject: [PATCH 091/291] More arrow adjustments to match the design --- osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs | 8 +++++--- osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs | 1 - osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs | 3 +-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 9178daac54..87dc8caf13 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -10,9 +10,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public class ArrowsOverlay : Container { - private const int glow_icon_size = 65; - private const int glow_icon_blur_sigma = 8; - private const float glow_icon_final_offset = 0.2f; + private const int glow_icon_size = 60; + private const int glow_icon_blur_sigma = 10; + private const float glow_icon_final_offset = 0.22f; private const float glow_icon_offscreen_offset = 0.6f; private const int blurred_icon_blur_sigma = 20; @@ -58,6 +58,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, + Alpha = 0.7f, X = - blurred_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_right, BlurSigma = new Vector2(blurred_icon_blur_sigma), @@ -67,6 +68,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, + Alpha = 0.7f, X = blurred_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_left, BlurSigma = new Vector2(blurred_icon_blur_sigma), diff --git a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs index 9e69d9d076..f16e7c7b96 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BlurredIcon.cs @@ -33,7 +33,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay public BlurredIcon() { RelativePositionAxes = Axes.X; - Alpha = 0.7f; CacheDrawnFrameBuffer = true; Child = icon = new SpriteIcon { diff --git a/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs index 81c2445324..b27eef632c 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/GlowIcon.cs @@ -18,8 +18,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { set { - blurredIcon.Size = value; - spriteIcon.Size = value - new Vector2(10); //Make it a bit smaller to make blur more visible + blurredIcon.Size = spriteIcon.Size = value; blurredIcon.ForceRedraw(); } get { return base.Size; } From ced620421913f255f20d271414f8c9206c3240a5 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 22 Sep 2017 22:10:05 +0300 Subject: [PATCH 092/291] oops --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 2 +- osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 27b7dc5408..bc0a0a2242 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -101,7 +101,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay remainingTimeBox .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) .Then() - .ResizeWidthTo(0, b.Duration); + .ResizeWidthTo(0, b.Duration - fade_duration); Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime); remainingTimeCounter.FadeIn(fade_duration); diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs index fbf3e10688..ab6ee5ea5c 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay var currentTime = Clock.CurrentTime; if (currentTime < remainingTime) { - int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0) + 1; + int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0); if (currentSecond != previousSecond) { counter.Text = currentSecond.ToString(); From e04526222cbf4f4024f680855b329b3251b84340 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Fri, 22 Sep 2017 22:47:26 +0200 Subject: [PATCH 093/291] 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 094/291] 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 2da3ea00b6a0bb550e2ab3a642632e6e363d6c01 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 23 Sep 2017 16:42:18 +0300 Subject: [PATCH 095/291] Bind break overlay to accuracy --- .../Play/BreaksOverlay/BreakOverlay.cs | 6 ++ .../Play/BreaksOverlay/InfoContainer.cs | 56 ++---------- .../Screens/Play/BreaksOverlay/InfoLine.cs | 89 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 5 +- osu.Game/osu.Game.csproj | 1 + 5 files changed, 109 insertions(+), 48 deletions(-) create mode 100644 osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index bc0a0a2242..e9dd112557 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Scoring; using System.Collections.Generic; namespace osu.Game.Screens.Play.BreaksOverlay @@ -119,5 +120,10 @@ namespace osu.Game.Screens.Play.BreaksOverlay info.FadeOut(fade_duration); arrowsOverlay.Hide(fade_duration); } + + public void BindProcessor(ScoreProcessor processor) + { + info.AccuracyDisplay.Current.BindTo(processor.Accuracy); + } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 75fcfcba0e..dc85fabbe0 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -2,16 +2,18 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Play.BreaksOverlay { public class InfoContainer : FillFlowContainer { + public PercentageInfoLine AccuracyDisplay; + public InfoLine RankDisplay; + public InfoLine GradeDisplay; + public InfoContainer() { AutoSizeAxes = Axes.Both; @@ -28,60 +30,20 @@ namespace osu.Game.Screens.Play.BreaksOverlay TextSize = 15, Font = "Exo2.0-Black", }, - new FillFlowContainer + new FillFlowContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Direction = FillDirection.Vertical, - Children = new [] + Children = new Drawable[] { - new InfoLine(@"Accuracy", @"-"), - new InfoLine(@"Rank", @"-"), - new InfoLine(@"Grade", @"-"), + AccuracyDisplay = new PercentageInfoLine(@"Accuracy"), + RankDisplay = new InfoLine(@"Rank", @"#"), + GradeDisplay = new InfoLine(@"Grade"), }, } }; } - - private class InfoLine : Container - { - private const int margin = 2; - - private readonly OsuSpriteText text; - private readonly OsuSpriteText valueText; - - public InfoLine(string name, string value) - { - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - Text = name, - TextSize = 17, - Margin = new MarginPadding { Right = margin } - }, - valueText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - Text = value, - TextSize = 17, - Font = "Exo2.0-Bold", - Margin = new MarginPadding { Left = margin } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - text.Colour = colours.Yellow; - valueText.Colour = colours.YellowLight; - } - } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs new file mode 100644 index 0000000000..0af766b321 --- /dev/null +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -0,0 +1,89 @@ +// 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Play.BreaksOverlay +{ + public class InfoLine : Container + where T : struct + { + private const int margin = 2; + + public Bindable Current = new Bindable(); + + private readonly OsuSpriteText text; + private readonly OsuSpriteText valueText; + + private readonly string prefix; + + public InfoLine(string name, string prefix = @"") + { + this.prefix = prefix; + + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Text = name, + TextSize = 17, + Margin = new MarginPadding { Right = margin } + }, + valueText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Text = prefix + @"-", + TextSize = 17, + Font = "Exo2.0-Bold", + Margin = new MarginPadding { Left = margin } + } + }; + + Current.ValueChanged += currentValueChanged; + } + + private void currentValueChanged(T newValue) + { + valueText.Text = prefix + Format(newValue); + } + + protected virtual string Format(T count) => count.ToString(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + text.Colour = colours.Yellow; + valueText.Colour = colours.YellowLight; + } + } + + public class PercentageInfoLine : InfoLine + { + public PercentageInfoLine(string name, string prefix = "") : base(name, prefix) + { + } + + protected override string Format(double count) => $@"{count:P2}"; + } + + public enum Grade + { + SSplus, + SS, + Splus, + S, + A, + B, + C, + F + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 86aa00875c..d8ddee0ac3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -67,6 +67,7 @@ namespace osu.Game.Screens.Play #endregion + private BreakOverlay breakOverlay; private HUDOverlay hudOverlay; private FailOverlay failOverlay; @@ -173,7 +174,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks) + breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -211,6 +212,8 @@ namespace osu.Game.Screens.Play hudOverlay.ModDisplay.Current.BindTo(working.Mods); + breakOverlay.BindProcessor(scoreProcessor); + // Bind ScoreProcessor to ourselves scoreProcessor.AllJudged += onCompletion; scoreProcessor.Failed += onFail; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index dd823f6144..2cbbc42061 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -280,6 +280,7 @@ + From a69bef8ec075d52e721ac3f0e89b2ee2e3ff4b11 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 23 Sep 2017 16:51:31 +0300 Subject: [PATCH 096/291] Use existing enum instead of my own --- osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs | 5 +++-- osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs | 12 ------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index dc85fabbe0..f6c47d757f 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -12,7 +13,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public PercentageInfoLine AccuracyDisplay; public InfoLine RankDisplay; - public InfoLine GradeDisplay; + public InfoLine GradeDisplay; public InfoContainer() { @@ -40,7 +41,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { AccuracyDisplay = new PercentageInfoLine(@"Accuracy"), RankDisplay = new InfoLine(@"Rank", @"#"), - GradeDisplay = new InfoLine(@"Grade"), + GradeDisplay = new InfoLine(@"Grade"), }, } }; diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs index 0af766b321..089dad6c38 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -74,16 +74,4 @@ namespace osu.Game.Screens.Play.BreaksOverlay protected override string Format(double count) => $@"{count:P2}"; } - - public enum Grade - { - SSplus, - SS, - Splus, - S, - A, - B, - C, - F - } } From d277952e0f72a7f3d78837d99627b002c4e5e0e2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 00:42:46 +0800 Subject: [PATCH 097/291] 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 0615f375e1b206a55eb36fe0f396127cb0a10be2 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 23 Sep 2017 19:52:44 +0300 Subject: [PATCH 098/291] Show current grade --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 1 + osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs | 5 ++--- osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs | 10 ++++++++++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index deb87e92d8..e8dd87a6a6 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Scoring Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; } - private ScoreRank rankFrom(double acc) + public static ScoreRank RankFrom(double acc) { if (acc == 1) return ScoreRank.X; @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Scoring score.Combo = Combo; score.MaxCombo = HighestCombo; score.Accuracy = Accuracy; - score.Rank = rankFrom(Accuracy); + score.Rank = RankFrom(Accuracy); score.Date = DateTimeOffset.Now; score.Health = Health; } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index e9dd112557..33fcebf3bb 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -124,6 +124,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay public void BindProcessor(ScoreProcessor processor) { info.AccuracyDisplay.Current.BindTo(processor.Accuracy); + info.GradeDisplay.Current.BindTo(processor.Accuracy); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index f6c47d757f..4cff9372a3 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -5,7 +5,6 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -13,7 +12,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public PercentageInfoLine AccuracyDisplay; public InfoLine RankDisplay; - public InfoLine GradeDisplay; + public GradeInfoLine GradeDisplay; public InfoContainer() { @@ -41,7 +40,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { AccuracyDisplay = new PercentageInfoLine(@"Accuracy"), RankDisplay = new InfoLine(@"Rank", @"#"), - GradeDisplay = new InfoLine(@"Grade"), + GradeDisplay = new GradeInfoLine(@"Grade"), }, } }; diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs index 089dad6c38..bf486e2480 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -74,4 +75,13 @@ namespace osu.Game.Screens.Play.BreaksOverlay protected override string Format(double count) => $@"{count:P2}"; } + + public class GradeInfoLine : InfoLine + { + public GradeInfoLine(string name, string prefix = "") : base(name, prefix) + { + } + + protected override string Format(double count) => $@"{ScoreProcessor.RankFrom(count)}"; + } } From 94269e119e3838914c5ab5c9f7ec4d65594d7553 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 23 Sep 2017 19:59:34 +0300 Subject: [PATCH 099/291] Reset text only if it has been changed --- osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs index bf486e2480..f74329ceb3 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -54,7 +54,12 @@ namespace osu.Game.Screens.Play.BreaksOverlay private void currentValueChanged(T newValue) { - valueText.Text = prefix + Format(newValue); + var newText = prefix + Format(newValue); + + if (valueText.Text == newText) + return; + + valueText.Text = newText; } protected virtual string Format(T count) => count.ToString(); From c5aebf6401fd9c28002c4fdeaaf6ef8e9edfaad2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 24 Sep 2017 03:23:31 +0800 Subject: [PATCH 100/291] 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 101/291] 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 102/291] 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 103/291] 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 104/291] 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 105/291] 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 106/291] 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 107/291] 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 108/291] 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 109/291] 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 110/291] 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 111/291] 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 112/291] 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 113/291] 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 114/291] 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 115/291] 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 116/291] 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 117/291] 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 118/291] 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 119/291] 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 120/291] 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 121/291] 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 122/291] 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 1f2a82b7ab3b3dba01bf1a44e3fe5e4b15e31db8 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Tue, 26 Sep 2017 12:21:00 +0200 Subject: [PATCH 123/291] make PreviewPlaying readonly instead of abstract --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 1 - osu.Game/Overlays/Direct/DirectListPanel.cs | 1 - osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 24ccd8b7eb..3c51235fad 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -27,7 +27,6 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; - public override Bindable PreviewPlaying { get; } = new Bindable(); public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7112e927bd..3aa8c8a7c2 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; - public override Bindable PreviewPlaying { get; } = new Bindable(); [BackgroundDependencyLoader] private void load(LocalisationEngine localisation, OsuColour colours) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 24cd8dc54e..65808c32a1 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; - public abstract Bindable PreviewPlaying { get; } + public readonly Bindable PreviewPlaying = new Bindable(); protected abstract PlayButton PlayButton { get; } protected override Container Content => content; From 10dbd68c1ee89be95c1844d62a8a698ab19c321d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Sep 2017 20:11:45 +0900 Subject: [PATCH 124/291] 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 From c696f7457883c11e8c771096e6bb36a1efd11ec6 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 27 Sep 2017 01:10:48 +0300 Subject: [PATCH 125/291] Fix broken testcase and apply suggested changes --- .../Screens/Play/BreaksOverlay/ArrowsOverlay.cs | 4 ++-- .../Screens/Play/BreaksOverlay/BreakOverlay.cs | 2 +- .../Screens/Play/BreaksOverlay/InfoContainer.cs | 8 ++++---- .../Play/BreaksOverlay/LetterboxOverlay.cs | 16 ++++++++-------- .../Play/BreaksOverlay/RemainingTimeCounter.cs | 10 +++++----- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 87dc8caf13..9d729826de 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, - X = - glow_icon_offscreen_offset, + X = -glow_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_right, BlurSigma = new Vector2(glow_icon_blur_sigma), Size = new Vector2(glow_icon_size), @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay Anchor = Anchor.Centre, Origin = Anchor.CentreRight, Alpha = 0.7f, - X = - blurred_icon_offscreen_offset, + X = -blurred_icon_offscreen_offset, Icon = Graphics.FontAwesome.fa_chevron_right, BlurSigma = new Vector2(blurred_icon_blur_sigma), Size = new Vector2(blurred_icon_size), diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 33fcebf3bb..90321df9d6 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay .Then() .ResizeWidthTo(0, b.Duration - fade_duration); - Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime); + Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); remainingTimeCounter.FadeIn(fade_duration); info.FadeIn(fade_duration); diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 4cff9372a3..8d2bec06aa 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Text = @"current progress".ToUpper(), + Text = "current progress".ToUpper(), TextSize = 15, Font = "Exo2.0-Black", }, @@ -38,9 +38,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay Direction = FillDirection.Vertical, Children = new Drawable[] { - AccuracyDisplay = new PercentageInfoLine(@"Accuracy"), - RankDisplay = new InfoLine(@"Rank", @"#"), - GradeDisplay = new GradeInfoLine(@"Grade"), + AccuracyDisplay = new PercentageInfoLine("Accuracy"), + RankDisplay = new InfoLine("Rank", @"#"), + GradeDisplay = new GradeInfoLine("Grade"), }, } }; diff --git a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs index c95b15ef3a..1581c45c56 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs @@ -11,9 +11,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public class LetterboxOverlay : Container { - private const int letterbox_height = 350; + private const int height = 350; - private Color4 transparentBlack => new Color4(0, 0, 0, 0); + private static readonly Color4 transparent_black = new Color4(0, 0, 0, 0); public LetterboxOverlay() { @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, RelativeSizeAxes = Axes.X, - Height = letterbox_height, + Height = height, Child = new Box { RelativeSizeAxes = Axes.Both, @@ -34,8 +34,8 @@ namespace osu.Game.Screens.Play.BreaksOverlay { TopLeft = Color4.Black, TopRight = Color4.Black, - BottomLeft = transparentBlack, - BottomRight = transparentBlack, + BottomLeft = transparent_black, + BottomRight = transparent_black, } } }, @@ -44,14 +44,14 @@ namespace osu.Game.Screens.Play.BreaksOverlay Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, - Height = letterbox_height, + Height = height, Child = new Box { RelativeSizeAxes = Axes.Both, Colour = new ColourInfo { - TopLeft = transparentBlack, - TopRight = transparentBlack, + TopLeft = transparent_black, + TopRight = transparent_black, BottomLeft = Color4.Black, BottomRight = Color4.Black, } diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs index ab6ee5ea5c..e89c1e292c 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay private int? previousSecond; - private double remainingTime; + private double endTime; private bool isCounting; @@ -31,9 +31,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay }; } - public void StartCounting(double remainingTime) + public void StartCounting(double endTime) { - this.remainingTime = remainingTime; + this.endTime = endTime; isCounting = true; } @@ -44,9 +44,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay if (isCounting) { var currentTime = Clock.CurrentTime; - if (currentTime < remainingTime) + if (currentTime < endTime) { - int currentSecond = (int)Math.Floor((remainingTime - Clock.CurrentTime) / 1000.0); + int currentSecond = (int)Math.Floor((endTime - Clock.CurrentTime) / 1000.0); if (currentSecond != previousSecond) { counter.Text = currentSecond.ToString(); From 708632bca84655c894e24da82a225112a9727f14 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 10:06:36 +0800 Subject: [PATCH 126/291] Remove second unnecessary colour set --- .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 3 --- 1 file changed, 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 d4a1177c4f..290412d170 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -99,9 +99,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Red; } } } From eae29820c069324333e37024315e7699ecc4da1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 11:06:33 +0800 Subject: [PATCH 127/291] Fix marker being cleared each beatmap change --- .../Components/Timelines/Summary/Parts/BookmarkPart.cs | 1 + .../Edit/Components/Timelines/Summary/Parts/BreakPart.cs | 1 + .../Components/Timelines/Summary/Parts/ControlPointPart.cs | 2 ++ .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 7 ++++++- .../Components/Timelines/Summary/Parts/TimelinePart.cs | 2 +- 5 files changed, 11 insertions(+), 2 deletions(-) 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 8afec62a08..1793cb4334 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -15,6 +15,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { protected override void LoadBeatmap(WorkingBeatmap beatmap) { + base.LoadBeatmap(beatmap); foreach (int bookmark in beatmap.BeatmapInfo.Bookmarks) Add(new BookmarkVisualisation(bookmark)); } 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 721825270b..004491d489 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -16,6 +16,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { protected override void LoadBeatmap(WorkingBeatmap beatmap) { + base.LoadBeatmap(beatmap); foreach (var breakPeriod in beatmap.Beatmap.Breaks) Add(new BreakVisualisation(breakPeriod)); } 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 e7f4f03f9b..d230578e13 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -18,6 +18,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { protected override void LoadBeatmap(WorkingBeatmap beatmap) { + base.LoadBeatmap(beatmap); + ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; cpi.TimingPoints.ForEach(addTimingPoint); 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 290412d170..228d32cee4 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -7,6 +7,7 @@ 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 @@ -61,10 +62,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override void Update() { base.Update(); - marker.X = (float)(Beatmap.Value?.Track.CurrentTime ?? 0); } + protected override void LoadBeatmap(WorkingBeatmap beatmap) + { + // block base call so we don't clear our marker (can be reused on beatmap change). + } + private class MarkerVisualisation : CompositeDrawable { public MarkerVisualisation() 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 f5d4124b19..8071aa9c59 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -25,7 +25,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts Beatmap.ValueChanged += b => { - timeline.Clear(); timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); LoadBeatmap(b); }; @@ -35,6 +34,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected virtual void LoadBeatmap(WorkingBeatmap beatmap) { + timeline.Clear(); } } } From 7ad21d9a6d09ba31c90041264b60f5e61a7ab79d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 11:07:23 +0800 Subject: [PATCH 128/291] Simplify marker part construction --- .../Components/Timelines/Summary/Parts/MarkerPart.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 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 228d32cee4..2e7eaf99f8 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -17,17 +17,15 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// internal class MarkerPart : TimelinePart { - private readonly Drawable marker; - - public MarkerPart() - { - Add(marker = new MarkerVisualisation()); - } + private Drawable marker; [BackgroundDependencyLoader] private void load(OsuColour colours) { - marker.Colour = colours.Red; + Add(marker = new MarkerVisualisation + { + Colour = colours.Red + }); } protected override bool OnDragStart(InputState state) => true; From d5ed218488aac139909012bb0343a69edf357421 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 11:07:43 +0800 Subject: [PATCH 129/291] Fix timeline sizes being updated potentially before the track has a length --- .../Timelines/Summary/Parts/TimelinePart.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) 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 8071aa9c59..75651640d5 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -25,11 +25,31 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts Beatmap.ValueChanged += b => { - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, b.Track.Length), 1); + updateRelativeChildSize(); LoadBeatmap(b); }; } + private void updateRelativeChildSize() + { + if (!Beatmap.Value.TrackLoaded) + { + timeline.RelativeChildSize = Vector2.One; + return; + } + + var track = Beatmap.Value.Track; + + if (!track.IsLoaded) + { + // the track may not be loaded completely (only has a length once it is). + Schedule(updateRelativeChildSize); + return; + } + + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, track.Length), 1); + } + protected void Add(Drawable visualisation) => timeline.Add(visualisation); protected virtual void LoadBeatmap(WorkingBeatmap beatmap) From 3018d32b13ec02cfb531ea38b9f237927105c564 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 11:22:47 +0800 Subject: [PATCH 130/291] Close BeatmapSetOverlay when clicking outside of it --- osu.Game/Overlays/BeatmapSetOverlay.cs | 3 +++ osu.Game/Overlays/UserProfileOverlay.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 8e28ad33c5..7a4c6338a1 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -23,6 +23,9 @@ namespace osu.Game.Overlays private readonly Header header; private readonly Info info; + // receive input outside our bounds so we can trigger a close event on ourselves. + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; + public BeatmapSetOverlay() { FirstWaveColour = OsuColour.Gray(0.4f); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f03ef3f1ed..088b0a1335 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays public const float CONTENT_X_MARGIN = 50; + // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; protected override bool OnClick(InputState state) From bbc990a6fd8be9ade98a74a7ad5c5bd19866660d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 11:26:56 +0800 Subject: [PATCH 131/291] Assign a name to individual import tests to avoid file contention --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index be48c997ea..9277310efc 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Beatmaps.IO 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()) + using (HeadlessGameHost host = new HeadlessGameHost("TestImportWhenClosed")) { var osu = loadOsu(host); @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Beatmaps.IO 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()) + using (HeadlessGameHost host = new HeadlessGameHost("TestImportWhenFileOpen")) { var osu = loadOsu(host); From 05c6829debe91a01c5a3b9ba0afe60b20f4a1773 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 12:18:24 +0800 Subject: [PATCH 132/291] Move all APIAccess State changes to the local thread Previously changes to the state were triggering events like Logout, which could get things into a bad state. --- osu.Game/Online/API/APIAccess.cs | 55 ++++++++++---------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 57f5c54a18..00abeea444 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -101,18 +101,16 @@ namespace osu.Game.Online.API } break; case APIState.Offline: + case APIState.Connecting: //work to restore a connection... if (!HasLogin) { - //OsuGame.Scheduler.Add(() => { OsuGame.ShowLogin(); }); - State = APIState.Offline; - Thread.Sleep(500); + Thread.Sleep(50); continue; } - if (State < APIState.Connecting) - State = APIState.Connecting; + State = APIState.Connecting; if (!authentication.HasValidAccessToken && !authentication.AuthenticateWithLogin(Username, Password)) { @@ -125,7 +123,8 @@ namespace osu.Game.Online.API var userReq = new GetUserRequest(); - userReq.Success += u => { + userReq.Success += u => + { LocalUser.Value = u; //we're connected! State = APIState.Online; @@ -133,16 +132,14 @@ namespace osu.Game.Online.API }; if (!handleRequest(userReq)) - { - State = APIState.Failing; continue; - } break; } //hard bail if we can't get a valid access token. if (authentication.RequestAccessToken() == null) { + Logout(false); State = APIState.Offline; continue; } @@ -162,20 +159,12 @@ namespace osu.Game.Online.API } } - private void clearCredentials() - { - Username = null; - Password = null; - } - public void Login(string username, string password) { Debug.Assert(State == APIState.Offline); Username = username; Password = password; - - State = APIState.Connecting; } /// @@ -204,7 +193,7 @@ namespace osu.Game.Online.API switch (statusCode) { case HttpStatusCode.Unauthorized: - State = APIState.Offline; + Logout(false); return true; case HttpStatusCode.RequestTimeout: failureCount++; @@ -215,6 +204,7 @@ namespace osu.Game.Online.API return false; State = APIState.Failing; + flushQueue(); return true; } @@ -242,26 +232,14 @@ namespace osu.Game.Online.API state = value; - switch (state) - { - case APIState.Failing: - case APIState.Offline: - flushQueue(); - break; - } - if (oldState != newState) { - //OsuGame.Scheduler.Add(delegate + log.Add($@"We just went {newState}!"); + Scheduler.Add(delegate { - //NotificationOverlay.ShowMessage($@"We just went {newState}!", newState == APIState.Online ? Color4.YellowGreen : Color4.OrangeRed, 5000); - log.Add($@"We just went {newState}!"); - Scheduler.Add(delegate - { - components.ForEach(c => c.APIStateChanged(this, newState)); - OnStateChange?.Invoke(oldState, newState); - }); - } + components.ForEach(c => c.APIStateChanged(this, newState)); + OnStateChange?.Invoke(oldState, newState); + }); } } } @@ -292,11 +270,12 @@ namespace osu.Game.Online.API } } - public void Logout() + public void Logout(bool clearUsername = true) { - clearCredentials(); + flushQueue(); + if (clearUsername) Username = null; + Password = null; authentication.Clear(); - State = APIState.Offline; LocalUser.Value = createGuestUser(); } From ec50834e98c2ac2a3ca3010fda4227a4555d2a89 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 12:23:48 +0800 Subject: [PATCH 133/291] Load osu!direct overlay to "newest maps" tab by default --- osu.Game/Overlays/Direct/Header.cs | 2 +- osu.Game/Overlays/DirectOverlay.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index 2c50fb453f..77743a3a4b 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Direct public Header() { - Tabs.Current.Value = DirectTab.Search; + Tabs.Current.Value = DirectTab.NewestMaps; Tabs.Current.TriggerChange(); } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9c07e1087f..5b5003b30f 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -251,7 +251,7 @@ namespace osu.Game.Overlays if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return; - getSetsRequest = new GetBeatmapSetsRequest(currentQuery, + getSetsRequest = new GetBeatmapSetsRequest(currentQuery.Value ?? string.Empty, ((FilterControl)Filter).Ruleset.Value, Filter.DisplayStyleControl.Dropdown.Current.Value, Filter.Tabs.Current.Value); //todo: sort direction (?) From faad3fc7d39291f59a6feb679b585224bf9e82dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 12:40:32 +0800 Subject: [PATCH 134/291] Arbitrarily move colour assignment --- .../Timelines/Summary/Parts/MarkerPart.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 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 2e7eaf99f8..0bdd081907 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -17,15 +17,11 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// internal class MarkerPart : TimelinePart { - private Drawable marker; + private readonly Drawable marker; - [BackgroundDependencyLoader] - private void load(OsuColour colours) + public MarkerPart() { - Add(marker = new MarkerVisualisation - { - Colour = colours.Red - }); + Add(marker = new MarkerVisualisation()); } protected override bool OnDragStart(InputState state) => true; @@ -102,6 +98,9 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } }; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Red; } } } From e64860ad45b44dfe27d36c1389d30af79e498e17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 12:46:34 +0800 Subject: [PATCH 135/291] Fix test case not working as expected --- .../Timelines/Summary/Parts/TimelinePart.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) 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 75651640d5..378ce78c67 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -32,22 +32,15 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { - if (!Beatmap.Value.TrackLoaded) + // the track may not be loaded completely (only has a length once it is). + if (!Beatmap.Value.Track.IsLoaded) { timeline.RelativeChildSize = Vector2.One; - return; - } - - var track = Beatmap.Value.Track; - - if (!track.IsLoaded) - { - // the track may not be loaded completely (only has a length once it is). Schedule(updateRelativeChildSize); return; } - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, track.Length), 1); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); } protected void Add(Drawable visualisation) => timeline.Add(visualisation); From 4a95d64239eb10b207604a9aaaa45a79c3024653 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 13:06:57 +0800 Subject: [PATCH 136/291] Fix yellow line in login overlay not following size correctly Also allows right click context menu to correctly extrude beyond the local masking. --- osu.Game/Overlays/LoginOverlay.cs | 49 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/LoginOverlay.cs b/osu.Game/Overlays/LoginOverlay.cs index 58b259fcbb..0a47637589 100644 --- a/osu.Game/Overlays/LoginOverlay.cs +++ b/osu.Game/Overlays/LoginOverlay.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Overlays.Settings.Sections.General; using OpenTK.Graphics; @@ -28,35 +29,43 @@ namespace osu.Game.Overlays { Children = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.6f, - }, new OsuContextMenuContainer { Width = 360, AutoSizeAxes = Axes.Y, - Masking = true, - AutoSizeDuration = transition_time, - AutoSizeEasing = Easing.OutQuint, Children = new Drawable[] { - settingsSection = new LoginSettings - { - Padding = new MarginPadding(10), - RequestHide = Hide, - }, new Box { - RelativeSizeAxes = Axes.X, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Height = 3, - Colour = colours.Yellow, - Alpha = 1, + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.6f, }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Masking = true, + AutoSizeDuration = transition_time, + AutoSizeEasing = Easing.OutQuint, + Children = new Drawable[] + { + settingsSection = new LoginSettings + { + Padding = new MarginPadding(10), + RequestHide = Hide, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Height = 3, + Colour = colours.Yellow, + Alpha = 1, + }, + } + } } } }; From a17cc04cdedc2455b19563977d3bf6b971de532e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 13:16:17 +0800 Subject: [PATCH 137/291] Make APIAccess's state only privately settable --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 00abeea444..bb72efb750 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -225,7 +225,7 @@ namespace osu.Game.Online.API public APIState State { get { return state; } - set + private set { APIState oldState = state; APIState newState = value; From 990ef3ca56d05cb424657545aa1770687ba63d4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Sep 2017 14:38:12 +0800 Subject: [PATCH 138/291] Make import tests more resilient to race condition failures Also centralises wait-or-assert logic. --- .../Beatmaps/IO/ImportBeatmapTest.cs | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 9277310efc..35bebf2d4f 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Beatmaps.IO ensureLoaded(osu); - Assert.IsFalse(File.Exists(temp)); + waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000); } } @@ -61,14 +61,13 @@ namespace osu.Game.Tests.Beatmaps.IO ensureLoaded(osu); - Assert.IsFalse(File.Exists(temp)); + waitForOrAssert(() => !File.Exists(temp), "Temporary still exists after IPC import", 5000); } } [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("TestImportWhenFileOpen")) { var osu = loadOsu(host); @@ -101,8 +100,7 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = new OsuGameBase(); Task.Run(() => host.Run(osu)); - while (!osu.IsLoaded) - Thread.Sleep(1); + waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time"); return osu; } @@ -113,30 +111,17 @@ namespace osu.Game.Tests.Beatmaps.IO 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."); + waitForOrAssert(() => (resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any(), + @"BeatmapSet did not import to the database in allocated time.", timeout); //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"); + waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, + @"Beatmaps did not import to the database in allocated time", timeout); var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First(); @@ -160,5 +145,11 @@ namespace osu.Game.Tests.Beatmaps.IO beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Count > 0); } + + private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) + { + Action waitAction = () => { while (!result()) Thread.Sleep(20); }; + Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage); + } } } From 545c375199703de17ccdecbd38b87427fb85bc71 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Sep 2017 21:53:33 +0900 Subject: [PATCH 139/291] Update design of EditorMenuBar to match flyte's design more closely --- osu-framework | 2 +- osu.Game/Screens/Edit/Editor.cs | 7 +- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 55 +++++++- .../Tests/Visual/TestCaseEditorMenuBar.cs | 125 ++++++++++-------- 4 files changed, 124 insertions(+), 65 deletions(-) diff --git a/osu-framework b/osu-framework index cdb031c3a8..a24fd77ad5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit cdb031c3a8ef693cd71458c5e19c68127ab72938 +Subproject commit a24fd77ad5f69e133a84175ef79c4ab7f600316b diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3ffd7754c1..d85026bb27 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -32,16 +32,11 @@ namespace osu.Game.Screens.Edit Height = 40, Children = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("111") - }, new EditorMenuBar { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - X = 100, + RelativeSizeAxes = Axes.Both, Items = new[] { new EditorMenuBarItem("File") diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index bb349b1531..818eb37bfb 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -19,8 +19,20 @@ namespace osu.Game.Screens.Edit.Menus public EditorMenuBar() : base(Direction.Horizontal, true) { - ItemsContainer.Padding = new MarginPadding(0); + RelativeSizeAxes = Axes.X; + + ItemsContainer.Padding = new MarginPadding { Left = 100 }; BackgroundColour = Color4.Transparent; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111"), + Depth = float.MaxValue + }, + }); } protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); @@ -32,9 +44,32 @@ namespace osu.Game.Screens.Edit.Menus private Color4 openedForegroundColour; private Color4 openedBackgroundColour; + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => parentSizedBox.ReceiveMouseInputAt(screenSpacePos); + + /// + /// A box with width equal to this 's width, and height equal to the parent height. + /// + private readonly Box parentSizedBox; + public DrawableEditorBarMenuItem(MenuItem item) : base(item) { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + AddInternal(parentSizedBox = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + BypassAutoSizeAxes = Axes.Both, + Alpha = 0, + }); + } + + public override void SetFlowDirection(Direction direction) + { + AutoSizeAxes = Axes.Both; } [BackgroundDependencyLoader] @@ -62,6 +97,13 @@ namespace osu.Game.Screens.Edit.Menus base.UpdateForegroundColour(); } + protected override void Update() + { + base.Update(); + + parentSizedBox.Height = Parent.DrawHeight; + } + protected override Drawable CreateBackground() => new Container { RelativeSizeAxes = Axes.Both, @@ -75,6 +117,17 @@ namespace osu.Game.Screens.Edit.Menus Child = new Box { RelativeSizeAxes = Axes.Both } } }; + + protected override DrawableOsuMenuItem.TextContainer CreateTextContainer() => new TextContainer(); + + private new class TextContainer : DrawableOsuMenuItem.TextContainer + { + public TextContainer() + { + NormalText.TextSize = BoldText.TextSize = 14; + NormalText.Margin = BoldText.Margin = new MarginPadding { Horizontal = 10, Vertical = MARGIN_VERTICAL }; + } + } } private class SubMenu : OsuMenu diff --git a/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs index 8b5132fe08..b0c21b6b8c 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs @@ -1,7 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; @@ -9,74 +12,82 @@ namespace osu.Game.Tests.Visual { public class TestCaseEditorMenuBar : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] { typeof(EditorMenuBar), typeof(ScreenSelectionTabControl) }; + public TestCaseEditorMenuBar() { - Add(new EditorMenuBar + Add(new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Height = 50, Y = 50, - Items = new[] + Child = new EditorMenuBar { - new EditorMenuBarItem("File") + RelativeSizeAxes = Axes.Both, + Items = new[] { - Items = new[] + new EditorMenuBarItem("File") { - new EditorMenuItem("Clear All Notes"), - new EditorMenuItem("Open Difficulty..."), - new EditorMenuItem("Save"), - new EditorMenuItem("Create a new Difficulty..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Revert to Saved"), - new EditorMenuItem("Revert to Saved (Full)"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Test Beatmap"), - new EditorMenuItem("Open AiMod"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Upload Beatmap..."), - new EditorMenuItem("Export Package"), - new EditorMenuItem("Export Map Package"), - new EditorMenuItem("Import from..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Open Song Folder"), - new EditorMenuItem("Open .osu in Notepad"), - new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Exit"), - } - }, - new EditorMenuBarItem("Timing") - { - Items = new[] + Items = new[] + { + new EditorMenuItem("Clear All Notes"), + new EditorMenuItem("Open Difficulty..."), + new EditorMenuItem("Save"), + new EditorMenuItem("Create a new Difficulty..."), + new EditorMenuItemSpacer(), + new EditorMenuItem("Revert to Saved"), + new EditorMenuItem("Revert to Saved (Full)"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Test Beatmap"), + new EditorMenuItem("Open AiMod"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Upload Beatmap..."), + new EditorMenuItem("Export Package"), + new EditorMenuItem("Export Map Package"), + new EditorMenuItem("Import from..."), + new EditorMenuItemSpacer(), + new EditorMenuItem("Open Song Folder"), + new EditorMenuItem("Open .osu in Notepad"), + new EditorMenuItem("Open .osb in Notepad"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Exit"), + } + }, + new EditorMenuBarItem("Timing") { - new EditorMenuItem("Time Signature"), - new EditorMenuItem("Metronome Clicks"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Add Timing Section"), - new EditorMenuItem("Add Inheriting Section"), - new EditorMenuItem("Reset Current Section"), - new EditorMenuItem("Delete Timing Section"), - new EditorMenuItem("Resnap Current Section"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Timing Setup"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), - new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), - new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorMenuItemSpacer(), - new EditorMenuItem("Set Current Position as Preview Point"), - } - }, - new EditorMenuBarItem("Testing") - { - Items = new[] + Items = new[] + { + new EditorMenuItem("Time Signature"), + new EditorMenuItem("Metronome Clicks"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Add Timing Section"), + new EditorMenuItem("Add Inheriting Section"), + new EditorMenuItem("Reset Current Section"), + new EditorMenuItem("Delete Timing Section"), + new EditorMenuItem("Resnap Current Section"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Timing Setup"), + new EditorMenuItemSpacer(), + new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorMenuItemSpacer(), + new EditorMenuItem("Set Current Position as Preview Point"), + } + }, + new EditorMenuBarItem("Testing") { - new EditorMenuItem("Item 1"), - new EditorMenuItem("Item 2"), - new EditorMenuItem("Item 3"), - } - }, + Items = new[] + { + new EditorMenuItem("Item 1"), + new EditorMenuItem("Item 2"), + new EditorMenuItem("Item 3"), + } + }, + } } }); } From ba8bf6cbd51bb6a7a6c48a4aa1d03fb459372742 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Sep 2017 22:01:53 +0900 Subject: [PATCH 140/291] Add ScreenSelectionTabControl to EditorMenuBar --- .../Graphics/UserInterface/OsuTabControl.cs | 8 +- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 6 ++ .../Edit/Menus/ScreenSelectionTabControl.cs | 84 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 89b1f4124b..b053195030 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -59,7 +59,7 @@ namespace osu.Game.Graphics.UserInterface public class OsuTabItem : TabItem, IHasAccentColour { protected readonly SpriteText Text; - private readonly Box box; + protected readonly Box Bar; private Color4 accentColour; public Color4 AccentColour @@ -77,13 +77,13 @@ namespace osu.Game.Graphics.UserInterface private void fadeActive() { - box.FadeIn(transition_length, Easing.OutQuint); + Bar.FadeIn(transition_length, Easing.OutQuint); Text.FadeColour(Color4.White, transition_length, Easing.OutQuint); } private void fadeInactive() { - box.FadeOut(transition_length, Easing.OutQuint); + Bar.FadeOut(transition_length, Easing.OutQuint); Text.FadeColour(AccentColour, transition_length, Easing.OutQuint); } @@ -123,7 +123,7 @@ namespace osu.Game.Graphics.UserInterface TextSize = 14, Font = @"Exo2.0-Bold", // Font should only turn bold when active? }, - box = new Box + Bar = new Box { RelativeSizeAxes = Axes.X, Height = 1, diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 818eb37bfb..a3b48d8c70 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -32,6 +32,12 @@ namespace osu.Game.Screens.Edit.Menus Colour = OsuColour.FromHex("111"), Depth = float.MaxValue }, + new ScreenSelectionTabControl + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + X = -15 + } }); } diff --git a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs new file mode 100644 index 0000000000..a455fa8d71 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using OpenTK; + +namespace osu.Game.Screens.Edit.Menus +{ + public class ScreenSelectionTabControl : OsuTabControl + { + public ScreenSelectionTabControl() + { + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + + TabContainer.RelativeSizeAxes &= ~Axes.X; + TabContainer.AutoSizeAxes = Axes.X; + TabContainer.Padding = new MarginPadding(); + + Add(new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + Colour = Color4.White.Opacity(0.2f), + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Yellow; + } + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(EditorScreenMode value) => new TabItem(value); + + private new class TabItem : OsuTabItem + { + private const float transition_length = 250; + + public TabItem(EditorScreenMode value) + : base(value) + { + Text.Margin = new MarginPadding(); + Text.Anchor = Anchor.CentreLeft; + Text.Origin = Anchor.CentreLeft; + } + + protected override void OnActivated() + { + base.OnActivated(); + Bar.ScaleTo(new Vector2(1, 5), transition_length, Easing.OutQuint); + } + + protected override void OnDeactivated() + { + base.OnDeactivated(); + Bar.ScaleTo(Vector2.One, transition_length, Easing.OutQuint); + } + } + } + + public enum EditorScreenMode + { + [System.ComponentModel.Description("compose")] + Compose, + [System.ComponentModel.Description("design")] + Design, + [System.ComponentModel.Description("timing")] + Timing, + [System.ComponentModel.Description("song")] + SongSetup + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a6860e4e8c..0afb0247df 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -618,6 +618,7 @@ + From 95364d0173cdc6db99b3ada2f20cdab6f4e8221c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Sep 2017 22:15:11 +0900 Subject: [PATCH 141/291] No more box background --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index a3b48d8c70..3142e3d6bc 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -22,16 +22,10 @@ namespace osu.Game.Screens.Edit.Menus RelativeSizeAxes = Axes.X; ItemsContainer.Padding = new MarginPadding { Left = 100 }; - BackgroundColour = Color4.Transparent; + BackgroundColour = OsuColour.FromHex("111"); AddRangeInternal(new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("111"), - Depth = float.MaxValue - }, new ScreenSelectionTabControl { Anchor = Anchor.BottomRight, From 8688d63a9e23117dec10cf3bc19c06e51b56b42f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Sep 2017 00:48:21 +0900 Subject: [PATCH 142/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index a24fd77ad5..9d142a8e00 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit a24fd77ad5f69e133a84175ef79c4ab7f600316b +Subproject commit 9d142a8e009794dfee828392e36025d08577131d From 4eaf6b4b94ac2850a15f1b9a775dba8201d7ebae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Sep 2017 00:08:42 +0800 Subject: [PATCH 143/291] Remove single usage of dynamic and stop referencing Microsoft.CSharp.dll --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 2 +- osu.Game/Rulesets/Scoring/Score.cs | 2 +- osu.Game/Screens/Ranking/ResultsPageScore.cs | 4 ++-- osu.Game/osu.Game.csproj | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 13bd8d288d..537fce2548 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Online.API.Requests } [JsonProperty(@"statistics")] - private Dictionary jsonStats + private Dictionary jsonStats { set { diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 7f053ec1c5..c4ffa4e93c 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -38,6 +38,6 @@ namespace osu.Game.Rulesets.Scoring public DateTimeOffset Date; - public Dictionary Statistics = new Dictionary(); + public Dictionary Statistics = new Dictionary(); } } diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index bf406ff912..b01410cff5 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -186,9 +186,9 @@ namespace osu.Game.Screens.Ranking private class DrawableScoreStatistic : Container { - private readonly KeyValuePair statistic; + private readonly KeyValuePair statistic; - public DrawableScoreStatistic(KeyValuePair statistic) + public DrawableScoreStatistic(KeyValuePair statistic) { this.statistic = statistic; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a6860e4e8c..bdca48ccdf 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -124,7 +124,6 @@ $(SolutionDir)\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll True - $(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll True From 75cd6eeb1c1b740cc62e713066e6d805f899bbe9 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 28 Sep 2017 14:20:19 +0300 Subject: [PATCH 144/291] Clean up Wave in WaveOverlayContainer --- osu.Game/Overlays/WaveOverlayContainer.cs | 37 +++-------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index 4f9783a762..77c532350b 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.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 osu.Framework; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics.Containers; @@ -165,10 +164,8 @@ namespace osu.Game.Overlays wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y)); } - private class Wave : Container, IStateful + private class Wave : VisibilityContainer { - public event Action StateChanged; - public float FinalPosition; public Wave() @@ -183,13 +180,7 @@ namespace osu.Game.Overlays Radius = 20f, }; - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - }, - }; + Child = new Box { RelativeSizeAxes = Axes.Both }; } protected override void Update() @@ -201,28 +192,8 @@ namespace osu.Game.Overlays Height = Parent.Parent.DrawSize.Y * 1.5f; } - private Visibility state; - - public Visibility State - { - get { return state; } - set - { - state = value; - - switch (value) - { - case Visibility.Hidden: - this.MoveToY(Parent.Parent.DrawSize.Y, DISAPPEAR_DURATION, easing_hide); - break; - case Visibility.Visible: - this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); - break; - } - - StateChanged?.Invoke(State); - } - } + protected override void PopIn() => this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); + protected override void PopOut() => this.MoveToY(Parent.Parent.DrawSize.Y, DISAPPEAR_DURATION, easing_hide); } } } From ca1f96208a00864209a8fa760a978fe75a217e0d Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 28 Sep 2017 14:31:02 +0300 Subject: [PATCH 145/291] Fix TestCaseContextMenu not being updated inline with previous changes --- osu.Game/Tests/Visual/TestCaseContextMenu.cs | 43 ++++++++++---------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseContextMenu.cs b/osu.Game/Tests/Visual/TestCaseContextMenu.cs index 28aae1f5b9..91a766f8c7 100644 --- a/osu.Game/Tests/Visual/TestCaseContextMenu.cs +++ b/osu.Game/Tests/Visual/TestCaseContextMenu.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; +using osu.Game.Graphics.Cursor; namespace osu.Game.Tests.Visual { @@ -23,32 +24,32 @@ namespace osu.Game.Tests.Visual public TestCaseContextMenu() { - Add(container = new MyContextMenuContainer + Add(new OsuContextMenuContainer { - Size = new Vector2(200), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new Box + container = new MyContextMenuContainer { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Green, - } - } - }); - - Add(new AnotherContextMenuContainer - { - Size = new Vector2(200), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Children = new Drawable[] - { - new Box + Size = new Vector2(200), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Green, + } + }, + new AnotherContextMenuContainer { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Red, + Size = new Vector2(200), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red, + } } } }); From 6bb5210c7cf6c97ec96f2094e62af0f41aa74efd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Sep 2017 15:09:28 +0900 Subject: [PATCH 146/291] Remove the parentSizedBox --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 3142e3d6bc..329471fd0a 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -44,27 +44,12 @@ namespace osu.Game.Screens.Edit.Menus private Color4 openedForegroundColour; private Color4 openedBackgroundColour; - public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => parentSizedBox.ReceiveMouseInputAt(screenSpacePos); - - /// - /// A box with width equal to this 's width, and height equal to the parent height. - /// - private readonly Box parentSizedBox; public DrawableEditorBarMenuItem(MenuItem item) : base(item) { Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; - - AddInternal(parentSizedBox = new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - BypassAutoSizeAxes = Axes.Both, - Alpha = 0, - }); } public override void SetFlowDirection(Direction direction) @@ -100,8 +85,6 @@ namespace osu.Game.Screens.Edit.Menus protected override void Update() { base.Update(); - - parentSizedBox.Height = Parent.DrawHeight; } protected override Drawable CreateBackground() => new Container From b2eab1f4351ad2b84a19706c35835ae9f98aad71 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Sep 2017 15:09:56 +0900 Subject: [PATCH 147/291] Set the hover background colour as dictated by flyte --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 25 +++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 329471fd0a..488ba220a2 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -41,9 +41,6 @@ namespace osu.Game.Screens.Edit.Menus private class DrawableEditorBarMenuItem : DrawableOsuMenuItem { - private Color4 openedForegroundColour; - private Color4 openedBackgroundColour; - public DrawableEditorBarMenuItem(MenuItem item) : base(item) @@ -52,24 +49,24 @@ namespace osu.Game.Screens.Edit.Menus Origin = Anchor.CentreLeft; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + ForegroundColour = colours.BlueLight; + BackgroundColour = Color4.Transparent; + ForegroundColourHover = Color4.White; + BackgroundColourHover = colours.Gray3; + } + public override void SetFlowDirection(Direction direction) { AutoSizeAxes = Axes.Both; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - ForegroundColour = ForegroundColourHover = colours.BlueLight; - BackgroundColour = BackgroundColourHover = Color4.Transparent; - openedForegroundColour = Color4.White; - openedBackgroundColour = colours.Gray3; - } - protected override void UpdateBackgroundColour() { if (State == MenuItemState.Selected) - Background.FadeColour(openedBackgroundColour); + Background.FadeColour(BackgroundColourHover); else base.UpdateBackgroundColour(); } @@ -77,7 +74,7 @@ namespace osu.Game.Screens.Edit.Menus protected override void UpdateForegroundColour() { if (State == MenuItemState.Selected) - Foreground.FadeColour(openedForegroundColour); + Foreground.FadeColour(ForegroundColourHover); else base.UpdateForegroundColour(); } From 775e8bada5e742a0ac62423fa1d61b6f3aa44047 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Sep 2017 15:10:24 +0900 Subject: [PATCH 148/291] Make the background bottom corners look nice with the new hover functionality --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 53 ++++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 488ba220a2..616cabbab2 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -41,12 +41,15 @@ namespace osu.Game.Screens.Edit.Menus private class DrawableEditorBarMenuItem : DrawableOsuMenuItem { + private BackgroundBox background; public DrawableEditorBarMenuItem(MenuItem item) : base(item) { Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; + + StateChanged += stateChanged; } [BackgroundDependencyLoader] @@ -79,25 +82,15 @@ namespace osu.Game.Screens.Edit.Menus base.UpdateForegroundColour(); } - protected override void Update() + private void stateChanged(MenuItemState newState) { - base.Update(); + if (newState == MenuItemState.Selected) + background.Expand(); + else + background.Contract(); } - protected override Drawable CreateBackground() => new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = new Container - { - RelativeSizeAxes = Axes.Both, - Height = 2, - Masking = true, - CornerRadius = 4, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }; - + protected override Drawable CreateBackground() => background = new BackgroundBox(); protected override DrawableOsuMenuItem.TextContainer CreateTextContainer() => new TextContainer(); private new class TextContainer : DrawableOsuMenuItem.TextContainer @@ -108,6 +101,34 @@ namespace osu.Game.Screens.Edit.Menus NormalText.Margin = BoldText.Margin = new MarginPadding { Horizontal = 10, Vertical = MARGIN_VERTICAL }; } } + + private class BackgroundBox : CompositeDrawable + { + private readonly Container innerBackground; + + public BackgroundBox() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + InternalChild = innerBackground = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Child = new Box { RelativeSizeAxes = Axes.Both } + }; + } + + /// + /// Expands the background such that it doesn't show the bottom corners. + /// + public void Expand() => innerBackground.Height = 2; + + /// + /// Contracts the background such that it shows the bottom corners. + /// + public void Contract() => innerBackground.Height = 1; + } } private class SubMenu : OsuMenu From 7b4348254c47d60aeb76a7ff7b8c695f36da4564 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Sep 2017 20:02:55 +0900 Subject: [PATCH 149/291] Don't use new --- osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs index a455fa8d71..516b954e44 100644 --- a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs +++ b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Menus protected override TabItem CreateTabItem(EditorScreenMode value) => new TabItem(value); - private new class TabItem : OsuTabItem + private class TabItem : OsuTabItem { private const float transition_length = 250; From 21c6a63fa1bc50e4ec5caf11618fd892cefda8ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Sep 2017 20:03:09 +0900 Subject: [PATCH 150/291] Use using for Description --- osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs index 516b954e44..652ef1d61f 100644 --- a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs +++ b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using OpenTK; +using System.ComponentModel; namespace osu.Game.Screens.Edit.Menus { @@ -72,13 +73,13 @@ namespace osu.Game.Screens.Edit.Menus public enum EditorScreenMode { - [System.ComponentModel.Description("compose")] + [Description("compose")] Compose, - [System.ComponentModel.Description("design")] + [Description("design")] Design, - [System.ComponentModel.Description("timing")] + [Description("timing")] Timing, - [System.ComponentModel.Description("song")] + [Description("song")] SongSetup } } From 40a27c810a7dabba9082475ed36aa0aa71872029 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 29 Sep 2017 19:24:14 +0800 Subject: [PATCH 151/291] Calculate SPM in spinner disc. --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 6577c7fd50..518fe188fb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -76,7 +76,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; + private double lastTime; public float RotationAbsolute; + public double SpinsPerMinute; private int completeTick; @@ -107,9 +109,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); + SpinsPerMinute = (thisAngle - lastAngle) / (Time.Current - lastTime) * 1000 * 60 / 360; } lastAngle = thisAngle; + lastTime = Time.Current; if (Complete && updateCompleteTick()) { From e2e26c91af5856851ab414186258683ce07d9b85 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 29 Sep 2017 22:30:41 +0800 Subject: [PATCH 152/291] Show SPM value basically. --- .../Objects/Drawables/DrawableSpinner.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 98dd40b0e6..c7e0353985 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Screens.Ranking; +using osu.Game.Graphics.Sprites; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -29,6 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; + private readonly OsuSpriteText spmText; private readonly SpriteIcon symbol; @@ -96,6 +98,24 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Origin = Anchor.Centre, }, circleContainer.CreateProxy(), + spmText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24, + Y = 120 + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 125 + }, ticks = new SpinnerTicks { Anchor = Anchor.Centre, @@ -167,6 +187,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; + spmText.Text = disc.SpinsPerMinute.ToString(@"#0"); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); From 647304c14bd1b247c6ac1df2dce51bcb3339e0ca Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:08:30 +0200 Subject: [PATCH 153/291] move logic to DirectPanel and reuse stuff for the PreviewButton --- osu.Game/Audio/AudioLoadWrapper.cs | 35 +++++ osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 128 +++++------------- osu.Game/Overlays/Direct/DirectGridPanel.cs | 13 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 14 +- osu.Game/Overlays/Direct/DirectPanel.cs | 53 ++++++++ osu.Game/Overlays/Direct/PlayButton.cs | 91 ++++++------- osu.Game/osu.Game.csproj | 1 + 7 files changed, 166 insertions(+), 169 deletions(-) create mode 100644 osu.Game/Audio/AudioLoadWrapper.cs diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs new file mode 100644 index 0000000000..8c013cf70f --- /dev/null +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -0,0 +1,35 @@ +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Audio +{ + public class AudioLoadWrapper : Drawable + { + private readonly string preview; + + public Track Preview; + + public AudioLoadWrapper(string preview) + { + this.preview = preview; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + if (!string.IsNullOrEmpty(preview)) + { + Preview = audio.Track.Get(preview); + Preview.Volume.Value = 0.5; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index bdb06106f0..9bb8b9a1a5 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -15,6 +15,9 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; +using osu.Game.Audio; +using osu.Game.Overlays.Direct; +using osu.Framework.Configuration; namespace osu.Game.Overlays.BeatmapSet { @@ -24,27 +27,10 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Container audioWrapper; private readonly Box bg, progress; - private readonly SpriteIcon icon; - private readonly LoadingAnimation loadingAnimation; + private readonly PlayButton playButton; private Track preview; - - private bool loading - { - set - { - if (value) - { - loadingAnimation.Show(); - icon.FadeOut(transition_duration * 5, Easing.OutQuint); - } - else - { - loadingAnimation.Hide(); - icon.FadeIn(transition_duration, Easing.OutQuint); - } - } - } + private readonly Bindable playing = new Bindable(); private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet @@ -55,42 +41,11 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - Playing = false; + playing.Value = false; preview = null; } } - private bool playing; - public bool Playing - { - get { return playing; } - set - { - if (value == playing) return; - playing = value; - - if (preview == null) - { - loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet) - { - OnLoadComplete = d => - { - loading = false; - - preview = (d as AudioLoadWrapper)?.Preview; - Playing = Playing; - updatePlayingState(); - }, - }); - - return; - } - - updatePlayingState(); - } - } - public PreviewButton() { Height = 42; @@ -116,22 +71,16 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - icon = new SpriteIcon + playButton = new PlayButton(playing) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.fa_play, Size = new Vector2(18), - Shadow = false, - }, - loadingAnimation = new LoadingAnimation - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, }, }; - Action = () => Playing = !Playing; + Action = () => playing.Value = !playing.Value; + playing.ValueChanged += updatePlayingState; } [BackgroundDependencyLoader] @@ -144,12 +93,12 @@ namespace osu.Game.Overlays.BeatmapSet { base.Update(); - if (Playing && preview != null) + if (playing.Value && preview != null) { progress.Width = (float)(preview.CurrentTime / preview.Length); if (preview.HasCompleted) { - Playing = false; + playing.Value = false; preview = null; } } @@ -157,7 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet protected override void Dispose(bool isDisposing) { - Playing = false; + playing.Value = false; base.Dispose(isDisposing); } @@ -173,44 +122,35 @@ namespace osu.Game.Overlays.BeatmapSet base.OnHoverLost(state); } - private void updatePlayingState() + private void updatePlayingState(bool newValue) { - if (preview == null) return; - - if (Playing) + if (preview == null) { - icon.Icon = FontAwesome.fa_stop; - progress.FadeIn(100); + playButton.Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet.OnlineInfo.Preview) + { + OnLoadComplete = d => + { + playButton.Loading = false; - preview.Seek(0); - preview.Start(); + preview = (d as AudioLoadWrapper)?.Preview; + playing.TriggerChange(); + }, + }); } else { - icon.Icon = FontAwesome.fa_play; - progress.FadeOut(100); - preview.Stop(); - } - } - - private class AudioLoadWrapper : Drawable - { - private readonly string preview; - - public Track Preview; - - public AudioLoadWrapper(BeatmapSetInfo set) - { - preview = set.OnlineInfo.Preview; - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - if (!string.IsNullOrEmpty(preview)) + if (newValue) { - Preview = audio.Track.Get(preview); - Preview.Volume.Value = 0.5; + progress.FadeIn(100); + + preview.Seek(0); + preview.Start(); + } + else + { + progress.FadeOut(100); + preview.Stop(); } } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 8a26ae906d..3b8cd20200 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -26,6 +26,7 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; + protected override Box PreviewBar => progressBar; public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { @@ -197,20 +198,8 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), Alpha = 0, - TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, }); - - PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - } - - protected override void Update() - { - base.Update(); - - if (PreviewPlaying && playButton.Track != null) - progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } } } diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index a9d7993f7a..6a73c15ee6 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -14,6 +14,7 @@ using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Framework.Configuration; +using System; namespace osu.Game.Overlays.Direct { @@ -33,6 +34,7 @@ namespace osu.Game.Overlays.Direct private Box progressBar; protected override PlayButton PlayButton => playButton; + protected override Box PreviewBar => progressBar; [BackgroundDependencyLoader] private void load(LocalisationEngine localisation, OsuColour colours) @@ -70,7 +72,6 @@ namespace osu.Game.Overlays.Direct Size = new Vector2(height / 2), FillMode = FillMode.Fit, Alpha = 0, - TrackUrl = "https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3", }, new FillFlowContainer { @@ -165,17 +166,6 @@ namespace osu.Game.Overlays.Direct Colour = colours.Yellow, }, }); - - PreviewPlaying.ValueChanged += newValue => playButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => progressBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - } - - protected override void Update() - { - base.Update(); - - if (PreviewPlaying && playButton.Track != null) - progressBar.Width = (float)(playButton.Track.CurrentTime / playButton.Track.Length); } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index c4c20da297..6b1e06fd3a 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -21,6 +21,8 @@ using osu.Framework.Logging; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; using osu.Framework.Configuration; +using osu.Framework.Audio.Track; +using osu.Game.Audio; namespace osu.Game.Overlays.Direct { @@ -39,9 +41,12 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; private BeatmapSetOverlay beatmapSetOverlay; + private Container audioWrapper; + protected Track Preview; public readonly Bindable PreviewPlaying = new Bindable(); protected abstract PlayButton PlayButton { get; } + protected abstract Box PreviewBar { get; } protected override Container Content => content; @@ -82,6 +87,7 @@ namespace osu.Game.Overlays.Direct EdgeEffect = edgeEffectNormal, Children = new[] { + audioWrapper = new Container(), // temporary blackness until the actual background loads. BlackBackground = new Box { @@ -106,6 +112,53 @@ namespace osu.Game.Overlays.Direct if (downloadRequest != null) attachDownload(downloadRequest); + + PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += setPlaying; + } + + private void setPlaying(bool newValue) + { + if (newValue) + { + if(Preview == null) + { + PlayButton.Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") + { + OnLoadComplete = d => + { + PlayButton.Loading = false; + Preview = (d as AudioLoadWrapper)?.Preview; + Preview.Start(); + }, + }); + } + else + { + Preview.Start(); + } + } + else + { + Preview?.Stop(); + } + } + + protected override void Update() + { + base.Update(); + + if (PreviewPlaying && Preview != null) + { + PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length); + if (Preview.HasCompleted) + { + PreviewPlaying.Value = false; + Preview = null; + } + } } protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index b0d011a81c..34b0ace1c5 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -11,81 +11,70 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using System.Threading.Tasks; namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - public string TrackUrl; - - public Bindable Playing; - - public Track Track; - private Bindable gameBeatmap; - private AudioManager audio; + private readonly Bindable playing; private Color4 hoverColour; private readonly SpriteIcon icon; + private readonly LoadingAnimation loadingAnimation; + private const float transition_duration = 500; + + private bool loading; + public bool Loading + { + get { return loading; } + set + { + loading = value; + if (value) + { + loadingAnimation.Show(); + icon.FadeOut(transition_duration * 5, Easing.OutQuint); + } + else + { + loadingAnimation.Hide(); + icon.FadeIn(transition_duration, Easing.OutQuint); + } + } + } public PlayButton(Bindable playing) { - Playing = playing; - Add(icon = new SpriteIcon + this.playing = playing; + AddRange(new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fit, - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.fa_play, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.fa_play, + }, + loadingAnimation = new LoadingAnimation(), }); - Playing.ValueChanged += newValue => icon.Icon = newValue ? (Track == null ? FontAwesome.fa_spinner : FontAwesome.fa_pause) : FontAwesome.fa_play; + playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; - Playing.ValueChanged += newValue => - { - if (newValue) - Track?.Start(); - else - Track?.Stop(); - }; - - Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); } [BackgroundDependencyLoader] - private void load(OsuColour colour, OsuGameBase game, AudioManager audio) + private void load(OsuColour colour) { hoverColour = colour.Yellow; - gameBeatmap = game.Beatmap; - this.audio = audio; } - private Task loadTask; - protected override bool OnClick(InputState state) { - gameBeatmap.Value.Track.Stop(); - - Playing.Value = !Playing.Value; - - if (loadTask == null) - { - icon.Spin(2000, RotationDirection.Clockwise); - - loadTask = Task.Run(() => - { - Track = audio.Track.Get(TrackUrl); - Track.Looping = true; - if (Playing) - Track.Start(); - - icon.ClearTransforms(); - icon.Rotation = 0; - Playing.TriggerChange(); - }); - } - + playing.Value = !playing.Value; return true; } @@ -97,7 +86,7 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!Playing) + if(!playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 95a15c06ba..3d81c5a539 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,6 +239,7 @@ + From 26e7a3f157ced6e6fb0ab01f05b9ec2abe2ab862 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:12:12 +0200 Subject: [PATCH 154/291] add license header --- osu.Game/Audio/AudioLoadWrapper.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index 8c013cf70f..69bf9d8147 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; From 2457df8e18b88006b3ecae32dd1ab0ac970a79e1 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:26:16 +0200 Subject: [PATCH 155/291] remove unused usings and reset the track to the start when playing again --- osu.Game/Audio/AudioLoadWrapper.cs | 5 ----- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 2 -- osu.Game/Overlays/Direct/DirectGridPanel.cs | 1 - osu.Game/Overlays/Direct/DirectListPanel.cs | 2 -- osu.Game/Overlays/Direct/DirectPanel.cs | 3 ++- osu.Game/Overlays/Direct/PlayButton.cs | 4 ---- 6 files changed, 2 insertions(+), 15 deletions(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index 69bf9d8147..efdde48564 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -6,11 +6,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Game.Beatmaps; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace osu.Game.Audio { diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index 9bb8b9a1a5..ea49963f67 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -12,7 +11,6 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; using osu.Game.Audio; diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 3b8cd20200..10611cd5be 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Framework.Configuration; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 6a73c15ee6..7f5fa3e3f0 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -13,8 +13,6 @@ using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Framework.Configuration; -using System; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 6b1e06fd3a..2195fc9ce7 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -131,12 +131,13 @@ namespace osu.Game.Overlays.Direct { PlayButton.Loading = false; Preview = (d as AudioLoadWrapper)?.Preview; - Preview.Start(); + PreviewPlaying.TriggerChange(); }, }); } else { + Preview.Seek(0); Preview.Start(); } } diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 34b0ace1c5..0405049c6a 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -3,16 +3,12 @@ using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using System.Threading.Tasks; namespace osu.Game.Overlays.Direct { From 59247bcf1eeef982a1ab442afcef0c3afa055561 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 29 Sep 2017 23:31:42 +0200 Subject: [PATCH 156/291] another unused using --- osu.Game/Audio/AudioLoadWrapper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs index efdde48564..67836d1690 100644 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ b/osu.Game/Audio/AudioLoadWrapper.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; -using osu.Game.Beatmaps; namespace osu.Game.Audio { From 92c3d722b4140020088fa8a471b6e24a2b8ad0b0 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 30 Sep 2017 05:41:32 +0300 Subject: [PATCH 157/291] Show mapper's profile when clicking on avatar in BeatmapSetOverlay --- osu.Game/OsuGame.cs | 6 ++--- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 28 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c137b8f6f5..75a1d61371 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -188,11 +188,11 @@ namespace osu.Game GetToolbarHeight = () => ToolbarOffset, Depth = -1 }, overlayContent.Add); - LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add); LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -2 }, mainContent.Add); + LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -3 }, mainContent.Add); LoadComponentAsync(musicController = new MusicController { - Depth = -3, + Depth = -4, Position = new Vector2(0, Toolbar.HEIGHT), Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -200,7 +200,7 @@ namespace osu.Game LoadComponentAsync(notificationOverlay = new NotificationOverlay { - Depth = -3, + Depth = -4, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, }, overlayContent.Add); diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index b0e4e49e31..fc9fd1e614 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -9,6 +9,9 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Game.Graphics.Containers; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.BeatmapSet { @@ -17,8 +20,11 @@ namespace osu.Game.Overlays.BeatmapSet private const float height = 50; private readonly UpdateableAvatar avatar; + private readonly ClickableArea clickableArea; private readonly FillFlowContainer fields; + private UserProfileOverlay profile; + private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet { @@ -31,6 +37,8 @@ namespace osu.Game.Overlays.BeatmapSet var i = BeatmapSet.OnlineInfo; avatar.User = i.Author; + clickableArea.Action = () => profile?.ShowUser(avatar.User); + fields.Children = new Drawable[] { new Field("made by", i.Author.Username, @"Exo2.0-RegularItalic"), @@ -58,11 +66,15 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - avatar = new UpdateableAvatar + clickableArea = new ClickableArea { - Size = new Vector2(height), + AutoSizeAxes = Axes.Both, CornerRadius = 3, Masking = true, + Child = avatar = new UpdateableAvatar + { + Size = new Vector2(height), + }, EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.25f), @@ -80,6 +92,13 @@ namespace osu.Game.Overlays.BeatmapSet }; } + [BackgroundDependencyLoader(true)] + private void load(UserProfileOverlay profile) + { + this.profile = profile; + clickableArea.Action = () => profile?.ShowUser(avatar.User); + } + private class Field : FillFlowContainer { public Field(string first, string second, string secondFont) @@ -103,5 +122,10 @@ namespace osu.Game.Overlays.BeatmapSet }; } } + + private class ClickableArea : OsuClickableContainer, IHasTooltip + { + public string TooltipText => @"View Profile"; + } } } From 3de42ee4050f8b08d7c0db3796e4d6913097dc9a Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 30 Sep 2017 15:23:10 +0800 Subject: [PATCH 158/291] Smooth spm values into a time range. --- .../Objects/Drawables/DrawableSpinner.cs | 3 ++- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index c7e0353985..6b9e91d4f4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.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.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -187,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; - spmText.Text = disc.SpinsPerMinute.ToString(@"#0"); + spmText.Text = Math.Truncate(disc.SpinsPerMinute).ToString(@"#0"); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 518fe188fb..04bbd8b871 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -76,9 +77,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; - private double lastTime; public float RotationAbsolute; public double SpinsPerMinute; + private readonly Queue rotations = new Queue(); + private readonly Queue times = new Queue(); + private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues private int completeTick; @@ -109,11 +112,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); - SpinsPerMinute = (thisAngle - lastAngle) / (Time.Current - lastTime) * 1000 * 60 / 360; + if (rotations.Count > 0) + { + float rotationFrom = rotations.Peek(); + double timeFrom = times.Peek(); + while (Time.Current - times.Peek() > spm_count_duration) + { + rotationFrom = rotations.Dequeue(); + timeFrom = times.Dequeue(); + } + SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + } } lastAngle = thisAngle; - lastTime = Time.Current; + rotations.Enqueue(currentRotation); + times.Enqueue(Time.Current); if (Complete && updateCompleteTick()) { From 5e751ea0ec38aabdf24bb80be772ee88eaf5274e Mon Sep 17 00:00:00 2001 From: "Franc[e]sco" Date: Sun, 1 Oct 2017 00:15:23 +0200 Subject: [PATCH 159/291] Only convert chords into strong hits for mania -> taiko --- .../Beatmaps/TaikoBeatmapConverter.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 4f2707ff88..ceaecbb555 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -55,14 +55,17 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Beatmap converted = base.ConvertBeatmap(original); - // Post processing step to transform hit objects with the same start time into strong hits - converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x => + if (original.BeatmapInfo.RulesetID == 3) { - TaikoHitObject first = x.First(); - if (x.Skip(1).Any()) - first.IsStrong = true; - return first; - }).ToList(); + // Post processing step to transform mania hit objects with the same start time into strong hits + converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x => + { + TaikoHitObject first = x.First(); + if (x.Skip(1).Any()) + first.IsStrong = true; + return first; + }).ToList(); + } return converted; } From b62f2437acc92d24d2b7f334cf53a3d9201fc84a Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sun, 1 Oct 2017 23:38:11 +0300 Subject: [PATCH 160/291] Don't allow counter became 0 --- osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs index e89c1e292c..c8b8b6a072 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay var currentTime = Clock.CurrentTime; if (currentTime < endTime) { - int currentSecond = (int)Math.Floor((endTime - Clock.CurrentTime) / 1000.0); + int currentSecond = (int)Math.Ceiling((endTime - Clock.CurrentTime) / 1000.0); if (currentSecond != previousSecond) { counter.Text = currentSecond.ToString(); From ac6c323f93ef73786845e3384675c91a664e1fb0 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 2 Oct 2017 00:44:57 +0300 Subject: [PATCH 161/291] Clear all tasks and transforms when resetting Breaks --- .../Play/BreaksOverlay/BreakOverlay.cs | 36 +++++++++++++++---- osu.Game/Tests/Visual/TestCaseBreakOverlay.cs | 4 --- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 90321df9d6..fe4d5ea424 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -5,9 +5,11 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Scoring; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -17,7 +19,21 @@ namespace osu.Game.Screens.Play.BreaksOverlay private const float remaining_time_container_max_size = 0.3f; private const int vertical_margin = 25; - public List Breaks; + private List breaks; + public List Breaks + { + set + { + breaks = value; + initializeBreaks(); + } + get + { + return breaks; + } + } + + private readonly List tasks = new List(); private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; @@ -71,15 +87,21 @@ namespace osu.Game.Screens.Play.BreaksOverlay protected override void LoadComplete() { base.LoadComplete(); - InitializeBreaks(); + initializeBreaks(); } - public void InitializeBreaks() + private void initializeBreaks() { - if (Breaks == null) + FinishTransforms(true); + + foreach (var t in tasks) + t.Cancel(); + tasks.Clear(); + + if (breaks == null) return; - foreach (var b in Breaks) + foreach (var b in breaks) { if (!b.HasEffect) continue; @@ -104,7 +126,9 @@ namespace osu.Game.Screens.Play.BreaksOverlay .Then() .ResizeWidthTo(0, b.Duration - fade_duration); - Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); + tasks.Add(new ScheduledDelegate(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime)); + Scheduler.Add(tasks.Last()); + remainingTimeCounter.FadeIn(fade_duration); info.FadeIn(fade_duration); diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 055a2bc5c4..074aa16934 100644 --- a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -37,8 +37,6 @@ namespace osu.Game.Tests.Visual EndTime = Clock.CurrentTime + duration, } }; - - breakOverlay.InitializeBreaks(); } private void startMultipleBreaks() @@ -58,8 +56,6 @@ namespace osu.Game.Tests.Visual EndTime = currentTime + 6000, } }; - - breakOverlay.InitializeBreaks(); } } } \ No newline at end of file From 2a9edcbb4f0754563d484f3e8acd2f0d9ea38c37 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 08:10:16 +0900 Subject: [PATCH 162/291] Add test case for the editor --- osu.Game/Tests/Visual/TestCaseEditor.cs | 47 +++++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 48 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseEditor.cs diff --git a/osu.Game/Tests/Visual/TestCaseEditor.cs b/osu.Game/Tests/Visual/TestCaseEditor.cs new file mode 100644 index 0000000000..6114d1eb2e --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseEditor.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.MathUtils; +using osu.Game.Beatmaps; +using osu.Game.Screens.Edit; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseEditor : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(Editor) }; + + private readonly Random rng; + + private BeatmapManager beatmaps; + private OsuGameBase osuGame; + + public TestCaseEditor() + { + rng = new Random(1337); + + Add(new Editor()); + AddStep("Next beatmap", nextBeatmap); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame, BeatmapManager beatmaps) + { + this.osuGame = osuGame; + this.beatmaps = beatmaps; + } + + private void nextBeatmap() + { + var sets = beatmaps.GetAllUsableBeatmapSets(); + if (sets.Count == 0) + return; + + BeatmapInfo info = sets[rng.Next(0, sets.Count)].Beatmaps[0]; + osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(info); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c8e42a3ad3..9dfc2401ae 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -742,6 +742,7 @@ + From 8ed23a60e97601226c80a00f7a5fa36e1cdaa683 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:10:40 +0900 Subject: [PATCH 163/291] Remove items from the editor menu bar --- osu.Game/Screens/Edit/Editor.cs | 146 +------------------------------- 1 file changed, 1 insertion(+), 145 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d85026bb27..6395e6c3b1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -36,151 +36,7 @@ namespace osu.Game.Screens.Edit { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - Items = new[] - { - new EditorMenuBarItem("File") - { - Items = new[] - { - new EditorMenuItem("Clear all notes"), - new EditorMenuItem("Open difficulty..."), - new EditorMenuItem("Save"), - new EditorMenuItem("Create new difficulty..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Revert to saved"), - new EditorMenuItem("Revert to saved (full"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Test beatmap"), - new EditorMenuItem("Open AiMod"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Upload Beatmap..."), - new EditorMenuItem("Export package"), - new EditorMenuItem("Export map package"), - new EditorMenuItem("Import from..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Open song folder"), - new EditorMenuItem("Open .osu in Notepad"), - new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, Exit) - } - }, - new EditorMenuBarItem("Edit") - { - Items = new[] - { - new EditorMenuItem("Undo"), - new EditorMenuItem("Redo"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Cut"), - new EditorMenuItem("Copy"), - new EditorMenuItem("Paste"), - new EditorMenuItem("Delete"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Select all"), - new EditorMenuItem("Clone"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Reverse selection"), - new EditorMenuItem("Flip horizontally"), - new EditorMenuItem("Flip vertically"), - new EditorMenuItem("Rotate 90deg clockwise"), - new EditorMenuItem("Rotate 90deg anticlockwise"), - new EditorMenuItem("Rotate by..."), - new EditorMenuItem("Scale by..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Reset selected objects' samples"), - new EditorMenuItem("Reset all samples", MenuItemType.Destructive), - new EditorMenuItem("Reset combo colours", MenuItemType.Destructive), - new EditorMenuItem("Reset breaks", MenuItemType.Destructive), - new EditorMenuItemSpacer(), - new EditorMenuItem("Nudge backward"), - new EditorMenuItem("Nudge forward") - } - }, - new EditorMenuBarItem("View") - { - Items = new[] - { - new EditorMenuItem("Compose"), - new EditorMenuItem("Design"), - new EditorMenuItem("Timing"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Song setup..."), - new EditorMenuItem("Timing setup..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Volume"), - new EditorMenuItem("Grid level"), - new EditorMenuItem("Show video"), - new EditorMenuItem("Show sample name"), - new EditorMenuItem("Snaking sliders"), - new EditorMenuItem("Hit animations"), - new EditorMenuItem("Follow points"), - new EditorMenuItem("Stacking") - } - }, - new EditorMenuBarItem("Compose") - { - Items = new[] - { - new EditorMenuItem("Snap divisor"), - new EditorMenuItem("Audio rate"), - new EditorMenuItem("Grid snapping"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Create polygon cricles..."), - new EditorMenuItem("Convert slider to stream"), - new EditorMenuItem("Enable live mapping mode"), - new EditorMenuItem("Sample import") - } - }, - new EditorMenuBarItem("Design") - { - Items = new[] - { - new EditorMenuItem("Move all elements in time...") - } - }, - new EditorMenuBarItem("Timing") - { - Items = new[] - { - new EditorMenuItem("Time signature"), - new EditorMenuItem("Metronome clicks"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Add timing section"), - new EditorMenuItem("Add inheriting section"), - new EditorMenuItem("Reset current section"), - new EditorMenuItem("Delete timing section"), - new EditorMenuItem("Resnap current section"), - new EditorMenuItemSpacer(), - new EditorMenuItem("Timing setup..."), - new EditorMenuItemSpacer(), - new EditorMenuItem("Resnap all notes", MenuItemType.Destructive), - new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive), - new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive), - new EditorMenuItemSpacer(), - new EditorMenuItem("Set current position as preview point") - } - }, - new EditorMenuBarItem("Web") - { - Items = new[] - { - new EditorMenuItem("This Beatmap's information page"), - new EditorMenuItem("This Beatmap's thread"), - new EditorMenuItem("Quick reply") - } - }, - new EditorMenuBarItem("Help") - { - Items = new[] - { - new EditorMenuItem("Show in-game help"), - new EditorMenuItem("View FAQ") - } - } - } + RelativeSizeAxes = Axes.Both } } }); From 7b1ef53f36fc60877bfacbe729ef72e71942a316 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:24:25 +0900 Subject: [PATCH 164/291] Expose a mode change event from EditorMenuBar --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 616cabbab2..4c9b3c84b3 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -11,11 +11,19 @@ using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; +using System; namespace osu.Game.Screens.Edit.Menus { public class EditorMenuBar : OsuMenu { + /// + /// Invaoked when the selected mode has changed. + /// + public event Action ModeChanged; + + private readonly ScreenSelectionTabControl tabControl; + public EditorMenuBar() : base(Direction.Horizontal, true) { @@ -26,13 +34,21 @@ namespace osu.Game.Screens.Edit.Menus AddRangeInternal(new Drawable[] { - new ScreenSelectionTabControl + tabControl = new ScreenSelectionTabControl { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, X = -15 } }); + + tabControl.Current.ValueChanged += v => ModeChanged?.Invoke(v); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + tabControl.Current.TriggerChange(); } protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); From 221902f4fefe2c94e0d546b0ecab4065bc198f33 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:26:16 +0900 Subject: [PATCH 165/291] Restructure Editor construction --- osu.Game/Screens/Edit/Editor.cs | 68 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 6395e6c3b1..8b6c0f0bf5 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -26,57 +26,61 @@ namespace osu.Game.Screens.Edit public Editor() { - Add(new Container + EditorMenuBar menuBar; + SummaryTimeline timeline; + + Children = new[] { - RelativeSizeAxes = Axes.X, - Height = 40, - Children = new Drawable[] + new Container { - new EditorMenuBar + Name = "Top bar", + RelativeSizeAxes = Axes.X, + Height = 40, + Child = menuBar = new EditorMenuBar { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Both } - } - }); - - SummaryTimeline summaryTimeline; - Add(new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 60, - Children = new Drawable[] + }, + new Container { - bottomBackground = new Box { RelativeSizeAxes = Axes.Both }, - new Container + Name = "Bottom bar", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, - Child = new FillFlowContainer + bottomBackground = new Box { RelativeSizeAxes = Axes.Both }, + new Container { - Name = "Bottom bar", RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new[] + Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, + Child = new FillFlowContainer { - summaryTimeline = new SummaryTimeline + Name = "Bottom bar", + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Width = 0.65f + timeline = new SummaryTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Width = 0.65f + } } } } } + }, } - }); + }; - summaryTimeline.Beatmap.BindTo(Beatmap); + timeline.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] From c2d63eb0bd9f239084f12de5c51aabab9e7477d8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:26:41 +0900 Subject: [PATCH 166/291] Add EditorScreen + screen changing functionality --- osu.Game/Screens/Edit/Editor.cs | 24 +++++++++++ osu.Game/Screens/Edit/Screens/EditorScreen.cs | 40 +++++++++++++++++++ osu.Game/Tests/Visual/TestCaseEditor.cs | 3 +- osu.Game/osu.Game.csproj | 1 + 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Edit/Screens/EditorScreen.cs diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8b6c0f0bf5..7f5ad0aa0a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -13,6 +13,7 @@ using osu.Game.Screens.Edit.Menus; using osu.Game.Screens.Edit.Components.Timelines.Summary; using OpenTK; using osu.Framework.Allocation; +using osu.Game.Screens.Edit.Screens; namespace osu.Game.Screens.Edit { @@ -23,6 +24,9 @@ namespace osu.Game.Screens.Edit internal override bool ShowOverlays => false; private readonly Box bottomBackground; + private readonly Container modeContainer; + + private EditorScreen currentScreen; public Editor() { @@ -77,10 +81,16 @@ namespace osu.Game.Screens.Edit } } }, + modeContainer = new Container + { + Name = "Screen container", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 40, Bottom = 60 } } }; timeline.Beatmap.BindTo(Beatmap); + menuBar.ModeChanged += onModeChanged; } [BackgroundDependencyLoader] @@ -89,6 +99,20 @@ namespace osu.Game.Screens.Edit bottomBackground.Colour = colours.Gray2; } + private void onModeChanged(EditorScreenMode mode) + { + currentScreen?.Exit(); + + switch (mode) + { + default: + currentScreen = new EditorScreen(); + break; + } + + modeContainer.Add(currentScreen); + } + protected override void OnResuming(Screen last) { Beatmap.Value.Track?.Stop(); diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs new file mode 100644 index 0000000000..49921a0025 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -0,0 +1,40 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; + +namespace osu.Game.Screens.Edit.Screens +{ + public class EditorScreen : CompositeDrawable + { + private readonly Container content; + + public EditorScreen() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + this.ScaleTo(0.5f).FadeTo(0) + .Then() + .ScaleTo(1f, 500, Easing.OutQuint).FadeTo(1f, 500, Easing.OutQuint); + } + + public void Exit() + { + this.ScaleTo(1.5f, 500).FadeOut(500f).Expire(); + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditor.cs b/osu.Game/Tests/Visual/TestCaseEditor.cs index 6114d1eb2e..6f7d05d299 100644 --- a/osu.Game/Tests/Visual/TestCaseEditor.cs +++ b/osu.Game/Tests/Visual/TestCaseEditor.cs @@ -7,12 +7,13 @@ using osu.Framework.Allocation; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Screens.Edit; +using osu.Game.Screens.Edit.Screens; namespace osu.Game.Tests.Visual { public class TestCaseEditor : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(Editor) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(Editor), typeof(EditorScreen) }; private readonly Random rng; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9dfc2401ae..94bd4862af 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -618,6 +618,7 @@ + From 2a310f02bcf0326f81d996ec72cd3076b1488436 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:27:27 +0900 Subject: [PATCH 167/291] modeContainer -> screenContainer --- osu.Game/Screens/Edit/Editor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7f5ad0aa0a..33b1f04cba 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Edit internal override bool ShowOverlays => false; private readonly Box bottomBackground; - private readonly Container modeContainer; + private readonly Container screenContainer; private EditorScreen currentScreen; @@ -81,7 +81,7 @@ namespace osu.Game.Screens.Edit } } }, - modeContainer = new Container + screenContainer = new Container { Name = "Screen container", RelativeSizeAxes = Axes.Both, @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Edit break; } - modeContainer.Add(currentScreen); + screenContainer.Add(currentScreen); } protected override void OnResuming(Screen last) From 6018b4e5e4b606e0c7fd65720153f7e6bfbaa34c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 09:34:51 +0900 Subject: [PATCH 168/291] Make EditorScreen a Container --- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index 49921a0025..ecc7ee1e7c 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -10,8 +10,9 @@ using osu.Framework.MathUtils; namespace osu.Game.Screens.Edit.Screens { - public class EditorScreen : CompositeDrawable + public class EditorScreen : Container { + protected override Container Content => content; private readonly Container content; public EditorScreen() From 91cede79c28e763110e0657f1108494f4144b953 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 10:07:34 +0900 Subject: [PATCH 169/291] Mask the editor screens --- osu.Game/Screens/Edit/Editor.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 33b1f04cba..05443420ef 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -81,11 +81,16 @@ namespace osu.Game.Screens.Edit } } }, - screenContainer = new Container + new Container { Name = "Screen container", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 40, Bottom = 60 } + Padding = new MarginPadding { Top = 40, Bottom = 60 }, + Child = screenContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true + } } }; From af4c6276e46b82b7a6779d2424b2dcad4284323e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 10:09:10 +0900 Subject: [PATCH 170/291] Adjust transforms of EditorScreen --- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index ecc7ee1e7c..8c4f6e7dbe 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -30,12 +30,12 @@ namespace osu.Game.Screens.Edit.Screens this.ScaleTo(0.5f).FadeTo(0) .Then() - .ScaleTo(1f, 500, Easing.OutQuint).FadeTo(1f, 500, Easing.OutQuint); + .ScaleTo(1f, 500, Easing.OutQuint).FadeTo(1f, 250, Easing.OutQuint); } public void Exit() { - this.ScaleTo(1.5f, 500).FadeOut(500f).Expire(); + this.ScaleTo(1.5f, 500).FadeOut(250).Expire(); } } } From 69b61a62a53ac1a23c1f5dafc1264fce51294a99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 10:09:21 +0900 Subject: [PATCH 171/291] Implement base Compose screen --- osu.Game/Screens/Edit/Editor.cs | 4 ++ .../Screens/Edit/Screens/Compose/Compose.cs | 42 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 3 files changed, 47 insertions(+) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Compose.cs diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 05443420ef..06b2a6de64 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,6 +14,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary; using OpenTK; using osu.Framework.Allocation; using osu.Game.Screens.Edit.Screens; +using osu.Game.Screens.Edit.Screens.Compose; namespace osu.Game.Screens.Edit { @@ -110,6 +111,9 @@ namespace osu.Game.Screens.Edit switch (mode) { + case EditorScreenMode.Compose: + currentScreen = new Compose(); + break; default: currentScreen = new EditorScreen(); break; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs new file mode 100644 index 0000000000..6da7fc900d --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class Compose : EditorScreen + { + public Compose() + { + Children = new[] + { + new Container + { + Name = "Timeline", + RelativeSizeAxes = Axes.X, + Height = 110, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f) + }, + new Container + { + Name = "Content", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 17, Vertical = 10 } + } + } + } + }; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94bd4862af..9a8536bbc2 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -619,6 +619,7 @@ + From 7211dd201546ae7293971431bd9c8a067137d56b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Oct 2017 10:11:43 +0900 Subject: [PATCH 172/291] Remove unnecessary usings --- osu.Game/Screens/Edit/Editor.cs | 1 - osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 1 - osu.Game/Screens/Edit/Screens/EditorScreen.cs | 4 ---- osu.Game/Tests/Visual/TestCaseEditor.cs | 1 - 4 files changed, 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 06b2a6de64..8a11a50fd6 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; 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.Timelines.Summary; using OpenTK; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 6da7fc900d..2fe40dd010 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -6,7 +6,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; namespace osu.Game.Screens.Edit.Screens.Compose { diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index 8c4f6e7dbe..c456ad6a51 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -1,12 +1,8 @@ // 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.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; namespace osu.Game.Screens.Edit.Screens { diff --git a/osu.Game/Tests/Visual/TestCaseEditor.cs b/osu.Game/Tests/Visual/TestCaseEditor.cs index 6f7d05d299..6da5e514b2 100644 --- a/osu.Game/Tests/Visual/TestCaseEditor.cs +++ b/osu.Game/Tests/Visual/TestCaseEditor.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Screens; From 5ce2723719f6697c03125142a5b4c66d808008c8 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 2 Oct 2017 05:12:56 +0300 Subject: [PATCH 173/291] Don't use linq query --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index fe4d5ea424..c7c5afe42c 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -9,7 +9,6 @@ using osu.Framework.Threading; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Scoring; using System.Collections.Generic; -using System.Linq; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -127,7 +126,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay .ResizeWidthTo(0, b.Duration - fade_duration); tasks.Add(new ScheduledDelegate(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime)); - Scheduler.Add(tasks.Last()); + Scheduler.Add(tasks[tasks.Count - 1]); remainingTimeCounter.FadeIn(fade_duration); From c2f487aa3edb9012fd97b58e8d5ae1b0cc8e4013 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 2 Oct 2017 05:56:38 +0300 Subject: [PATCH 174/291] Add Rank as a property to the Score Processor --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 11 +++++++++-- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 2 +- osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs | 5 +++-- osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs | 10 ---------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index e8dd87a6a6..0b631a7148 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -51,6 +51,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt Combo = new BindableInt(); + /// + /// The current rank. + /// + public readonly Bindable Rank = new Bindable(ScoreRank.X); + /// /// THe highest combo achieved by this score. /// @@ -74,9 +79,10 @@ namespace osu.Game.Rulesets.Scoring protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; + Accuracy.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; } - public static ScoreRank RankFrom(double acc) + private ScoreRank rankFrom(double acc) { if (acc == 1) return ScoreRank.X; @@ -101,6 +107,7 @@ namespace osu.Game.Rulesets.Scoring Accuracy.Value = 1; Health.Value = 1; Combo.Value = 0; + Rank.Value = ScoreRank.X; HighestCombo.Value = 0; alreadyFailed = false; @@ -142,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring score.Combo = Combo; score.MaxCombo = HighestCombo; score.Accuracy = Accuracy; - score.Rank = RankFrom(Accuracy); + score.Rank = Rank; score.Date = DateTimeOffset.Now; score.Health = Health; } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index c7c5afe42c..53a2f4919e 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay public void BindProcessor(ScoreProcessor processor) { info.AccuracyDisplay.Current.BindTo(processor.Accuracy); - info.GradeDisplay.Current.BindTo(processor.Accuracy); + info.GradeDisplay.Current.BindTo(processor.Rank); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 8d2bec06aa..351dc66930 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -12,7 +13,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { public PercentageInfoLine AccuracyDisplay; public InfoLine RankDisplay; - public GradeInfoLine GradeDisplay; + public InfoLine GradeDisplay; public InfoContainer() { @@ -40,7 +41,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay { AccuracyDisplay = new PercentageInfoLine("Accuracy"), RankDisplay = new InfoLine("Rank", @"#"), - GradeDisplay = new GradeInfoLine("Grade"), + GradeDisplay = new InfoLine("Grade"), }, } }; diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs index f74329ceb3..751523d68c 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoLine.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.BreaksOverlay { @@ -80,13 +79,4 @@ namespace osu.Game.Screens.Play.BreaksOverlay protected override string Format(double count) => $@"{count:P2}"; } - - public class GradeInfoLine : InfoLine - { - public GradeInfoLine(string name, string prefix = "") : base(name, prefix) - { - } - - protected override string Format(double count) => $@"{ScoreProcessor.RankFrom(count)}"; - } } From 70524628635d5a17535bc4f4277261164b85750c Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 2 Oct 2017 08:51:00 +0300 Subject: [PATCH 175/291] Update inline with framework --- osu-framework | 2 +- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/osu-framework b/osu-framework index 9d142a8e00..5f19dd913d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9d142a8e009794dfee828392e36025d08577131d +Subproject commit 5f19dd913dfc69013a3b9cf30ccfd9c44881a321 diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 53a2f4919e..9ffaf906c8 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -5,7 +5,6 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Threading; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Scoring; using System.Collections.Generic; @@ -32,8 +31,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay } } - private readonly List tasks = new List(); - private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; private readonly Container remainingTimeBox; @@ -92,10 +89,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay private void initializeBreaks() { FinishTransforms(true); - - foreach (var t in tasks) - t.Cancel(); - tasks.Clear(); + Scheduler.CancelDelayedTasks(); if (breaks == null) return; @@ -125,8 +119,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay .Then() .ResizeWidthTo(0, b.Duration - fade_duration); - tasks.Add(new ScheduledDelegate(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime)); - Scheduler.Add(tasks[tasks.Count - 1]); + Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); remainingTimeCounter.FadeIn(fade_duration); From b6ed977e1e383a388b57f557e707cff546ee56f0 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 2 Oct 2017 09:04:03 +0300 Subject: [PATCH 176/291] Fix hard crash and fix breaks have been initialized twice --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 6 ------ osu.Game/Screens/Play/Player.cs | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 9ffaf906c8..3b2335a455 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -80,12 +80,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay }; } - protected override void LoadComplete() - { - base.LoadComplete(); - initializeBreaks(); - } - private void initializeBreaks() { FinishTransforms(true); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 79ace6c45a..589f4b663a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -192,8 +192,8 @@ namespace osu.Game.Screens.Play { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Breaks = beatmap.Breaks, - Clock = decoupledClock + Clock = decoupledClock, + Breaks = beatmap.Breaks }, } }, From 66afba62190f56c698678a4fb4ad03e280ed8318 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2017 17:38:48 +0800 Subject: [PATCH 177/291] Allow TestCasePlayer to instantiate only one ruleset type --- .../Tests/TestCaseCatchPlayer.cs | 4 +++ osu.Game/Rulesets/RulesetStore.cs | 1 - osu.Game/Tests/Visual/TestCasePlayer.cs | 31 ++++++++++++------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index 8d18a712d8..45ab8ac300 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -10,6 +10,10 @@ namespace osu.Game.Rulesets.Catch.Tests [TestFixture] public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer { + public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) + { + + } protected override Beatmap CreateBeatmap() { var beatmap = new Beatmap(); diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 5eef4a8470..407a5f7c3c 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -38,7 +38,6 @@ namespace osu.Game.Rulesets protected override void Prepare(bool reset = false) { - Connection.CreateTable(); if (reset) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 4a25a52e36..b0953ceb7e 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.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.IO; using System.Linq; using System.Text; @@ -18,31 +19,39 @@ namespace osu.Game.Tests.Visual { public class TestCasePlayer : OsuTestCase { + private readonly Type ruleset; + protected Player Player; - private RulesetStore rulesets; public override string Description => @"Showing everything to play the game."; + /// + /// Create a TestCase which runs through the Player screen. + /// + /// An optional ruleset type which we want to target. If not provided we'll allow all rulesets to be tested. + protected TestCasePlayer(Type ruleset) + { + this.ruleset = ruleset; + } + + public TestCasePlayer() + { + + } + [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - this.rulesets = rulesets; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - Add(new Box { RelativeSizeAxes = Framework.Graphics.Axes.Both, Colour = Color4.Black, }); - foreach (var r in rulesets.Query()) - AddStep(r.Name, () => loadPlayerFor(r)); + string instantiation = ruleset?.AssemblyQualifiedName; - loadPlayerFor(rulesets.Query().First()); + foreach (var r in rulesets.Query(rs => rs.Available && (instantiation == null || rs.InstantiationInfo == instantiation))) + AddStep(r.Name, () => loadPlayerFor(r)); } protected virtual Beatmap CreateBeatmap() From 12a9cbad56b84960226b21204ee2e6453d67d9a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2017 21:54:26 +0800 Subject: [PATCH 178/291] Allow Beatmap to populate some metadata defaults if they aren't provided via BetamapInfo --- osu.Game/Beatmaps/Beatmap.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 458c2304f2..383a331eb4 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -58,6 +58,23 @@ namespace osu.Game.Beatmaps ComboColors = original?.ComboColors ?? ComboColors; HitObjects = original?.HitObjects ?? HitObjects; Storyboard = original?.Storyboard ?? Storyboard; + + if (original == null && Metadata == null) + { + // we may have no metadata in cases we weren't sourced from the database. + // let's fill it (and other related fields) so we don't need to null-check it in future usages. + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Artist = @"Unknown", + Title = @"Unknown", + Author = @"Unknown Creator", + }, + Version = @"Normal", + Difficulty = new BeatmapDifficulty() + }; + } } } From 7168629b2a28f59a121a844b45f481b138e3df0d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2017 21:55:37 +0800 Subject: [PATCH 179/291] Remove CatcherArea abstraction Also fixes catcher size being relative to aspect ratio. --- .../Tests/TestCaseCatcher.cs | 4 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 34 ++- osu.Game.Rulesets.Catch/UI/Catcher.cs | 193 +++++++++++++++ osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 229 ------------------ .../osu.Game.Rulesets.Catch.csproj | 2 +- 5 files changed, 225 insertions(+), 237 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/UI/Catcher.cs delete mode 100644 osu.Game.Rulesets.Catch/UI/CatcherArea.cs diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatcher.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatcher.cs index 6a065e197d..21a9bdec51 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatcher.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatcher.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Tests { public override IReadOnlyList RequiredTypes => new[] { - typeof(CatcherArea), + typeof(Catcher), }; [BackgroundDependencyLoader] @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests new CatchInputManager(rulesets.GetRuleset(2)) { RelativeSizeAxes = Axes.Both, - Child = new CatcherArea + Child = new Catcher { RelativePositionAxes = Axes.Both, RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 2b6f9bbf5a..38f3273055 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -1,10 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Graphics; using osu.Game.Rulesets.UI; using OpenTK; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; @@ -15,11 +17,15 @@ namespace osu.Game.Rulesets.Catch.UI { protected override Container Content => content; private readonly Container content; - private readonly CatcherArea catcherArea; + + private readonly Container catcherContainer; + private readonly Catcher catcher; public CatchPlayfield() : base(Axes.Y) { + Container explodingFruitContainer; + Reversed.Value = true; Size = new Vector2(1); @@ -33,16 +39,34 @@ namespace osu.Game.Rulesets.Catch.UI { RelativeSizeAxes = Axes.Both, }, - catcherArea = new CatcherArea + explodingFruitContainer = new Container { RelativeSizeAxes = Axes.Both, + }, + catcherContainer = new Container { + RelativeSizeAxes = Axes.X, Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, - Height = 0.3f + Height = 180, + Child = catcher = new Catcher + { + ExplodingFruitTarget = explodingFruitContainer, + RelativePositionAxes = Axes.Both, + Origin = Anchor.TopCentre, + X = 0.5f, + } } }; } + protected override void Update() + { + base.Update(); + catcher.Size = new Vector2(catcherContainer.DrawSize.Y); + } + + public bool CheckIfWeCanCatch(CatchBaseHit obj) => Math.Abs(catcher.Position.X - obj.X) < catcher.DrawSize.X / DrawSize.X / 2; + public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; @@ -50,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.UI base.Add(h); var fruit = (DrawableFruit)h; - fruit.CheckPosition = catcherArea.CheckIfWeCanCatch; + fruit.CheckPosition = CheckIfWeCanCatch; } public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) @@ -59,7 +83,7 @@ namespace osu.Game.Rulesets.Catch.UI { Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; Remove(judgedObject); - catcherArea.Add(judgedObject, screenPosition); + catcher.Add(judgedObject, screenPosition); } } } diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs new file mode 100644 index 0000000000..87fe95ed2f --- /dev/null +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -0,0 +1,193 @@ +// 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 osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Bindings; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using OpenTK; + +namespace osu.Game.Rulesets.Catch.UI +{ + public class Catcher : Container, IKeyBindingHandler + { + private Texture texture; + + private Container caughtFruit; + + public Container ExplodingFruitTarget; + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + texture = textures.Get(@"Play/Catch/fruit-catcher-idle"); + + Children = new Drawable[] + { + createCatcherSprite(), + caughtFruit = new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + } + }; + } + + private int currentDirection; + + private bool dashing; + + protected bool Dashing + { + get { return dashing; } + set + { + if (value == dashing) return; + + dashing = value; + + if (dashing) + Schedule(addAdditiveSprite); + } + } + + private void addAdditiveSprite() + { + if (!dashing) return; + + var additive = createCatcherSprite(); + + additive.RelativePositionAxes = Axes.Both; + additive.Blending = BlendingMode.Additive; + additive.Position = Position; + additive.Scale = Scale; + + ((Container)Parent).Add(additive); + + additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint).Expire(); + + Scheduler.AddDelayed(addAdditiveSprite, 50); + } + + private Sprite createCatcherSprite() => new Sprite + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Texture = texture, + OriginPosition = new Vector2(DrawWidth / 2, 10) //temporary until the sprite is aligned correctly. + }; + + public bool OnPressed(CatchAction action) + { + switch (action) + { + case CatchAction.MoveLeft: + currentDirection--; + return true; + case CatchAction.MoveRight: + currentDirection++; + return true; + case CatchAction.Dash: + Dashing = true; + return true; + } + + return false; + } + + public bool OnReleased(CatchAction action) + { + switch (action) + { + case CatchAction.MoveLeft: + currentDirection++; + return true; + case CatchAction.MoveRight: + currentDirection--; + return true; + case CatchAction.Dash: + Dashing = false; + return true; + } + + return false; + } + + /// + /// The relative space to cover in 1 millisecond. based on 1 game pixel per millisecond as in osu-stable. + /// + private const double base_speed = 1.0 / 512; + + protected override void Update() + { + base.Update(); + + if (currentDirection == 0) return; + + double dashModifier = Dashing ? 1 : 0.5; + + Scale = new Vector2(Math.Sign(currentDirection), 1); + X = (float)MathHelper.Clamp(X + Math.Sign(currentDirection) * Clock.ElapsedFrameTime * base_speed * dashModifier, 0, 1); + } + + public void Add(DrawableHitObject fruit, Vector2 absolutePosition) + { + fruit.RelativePositionAxes = Axes.None; + fruit.Position = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0); + + fruit.Anchor = Anchor.TopCentre; + fruit.Origin = Anchor.BottomCentre; + fruit.Scale *= 0.7f; + fruit.LifetimeEnd = double.MaxValue; + + float distance = fruit.DrawSize.X / 2 * fruit.Scale.X; + + while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance)) + { + fruit.X += RNG.Next(-5, 5); + fruit.Y -= RNG.Next(0, 5); + } + + caughtFruit.Add(fruit); + + if (((CatchBaseHit)fruit.HitObject).LastInCombo) + explode(); + } + + private void explode() + { + var fruit = caughtFruit.ToArray(); + + foreach (var f in fruit) + { + var originalX = f.X * Scale.X; + + if (ExplodingFruitTarget != null) + { + f.Anchor = Anchor.TopLeft; + f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget); + + caughtFruit.Remove(f); + + ExplodingFruitTarget.Add(f); + } + + f.MoveToY(f.Y - 50, 250, Easing.OutSine) + .Then() + .MoveToY(f.Y + 50, 500, Easing.InSine); + + f.MoveToX(f.X + originalX * 6, 1000); + f.FadeOut(750); + + f.Expire(); + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs deleted file mode 100644 index 2930dbb7cc..0000000000 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ /dev/null @@ -1,229 +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 osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Bindings; -using osu.Framework.MathUtils; -using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Objects.Drawables; -using OpenTK; - -namespace osu.Game.Rulesets.Catch.UI -{ - public class CatcherArea : Container - { - private Catcher catcher; - private Container explodingFruitContainer; - - public void Add(DrawableHitObject fruit, Vector2 screenPosition) => catcher.AddToStack(fruit, screenPosition); - - public bool CheckIfWeCanCatch(CatchBaseHit obj) => Math.Abs(catcher.Position.X - obj.X) < catcher.DrawSize.X / DrawSize.X / 2; - - [BackgroundDependencyLoader] - private void load() - { - Children = new Drawable[] - { - explodingFruitContainer = new Container - { - RelativeSizeAxes = Axes.Both, - }, - catcher = new Catcher - { - RelativePositionAxes = Axes.Both, - ExplodingFruitTarget = explodingFruitContainer, - Origin = Anchor.TopCentre, - X = 0.5f, - } - }; - } - - protected override void Update() - { - base.Update(); - - catcher.Size = new Vector2(DrawSize.Y); - } - - private class Catcher : Container, IKeyBindingHandler - { - private Texture texture; - - private Container caughtFruit; - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - texture = textures.Get(@"Play/Catch/fruit-catcher-idle"); - - Children = new Drawable[] - { - createCatcherSprite(), - caughtFruit = new Container - { - Anchor = Anchor.TopCentre, - Origin = Anchor.BottomCentre, - } - }; - } - - private int currentDirection; - - private bool dashing; - - public Container ExplodingFruitTarget; - - protected bool Dashing - { - get { return dashing; } - set - { - if (value == dashing) return; - - dashing = value; - - if (dashing) - Schedule(addAdditiveSprite); - } - } - - private void addAdditiveSprite() - { - if (!dashing) return; - - var additive = createCatcherSprite(); - - additive.RelativePositionAxes = Axes.Both; - additive.Blending = BlendingMode.Additive; - additive.Position = Position; - additive.Scale = Scale; - - ((CatcherArea)Parent).Add(additive); - - additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint).Expire(); - - Scheduler.AddDelayed(addAdditiveSprite, 50); - } - - private Sprite createCatcherSprite() => new Sprite - { - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit, - Texture = texture, - OriginPosition = new Vector2(DrawWidth / 2, 10) //temporary until the sprite is aligned correctly. - }; - - public bool OnPressed(CatchAction action) - { - switch (action) - { - case CatchAction.MoveLeft: - currentDirection--; - return true; - case CatchAction.MoveRight: - currentDirection++; - return true; - case CatchAction.Dash: - Dashing = true; - return true; - } - - return false; - } - - public bool OnReleased(CatchAction action) - { - switch (action) - { - case CatchAction.MoveLeft: - currentDirection++; - return true; - case CatchAction.MoveRight: - currentDirection--; - return true; - case CatchAction.Dash: - Dashing = false; - return true; - } - - return false; - } - - /// - /// The relative space to cover in 1 millisecond. based on 1 game pixel per millisecond as in osu-stable. - /// - private const double base_speed = 1.0 / 512; - - protected override void Update() - { - base.Update(); - - if (currentDirection == 0) return; - - double dashModifier = Dashing ? 1 : 0.5; - - Scale = new Vector2(Math.Sign(currentDirection), 1); - X = (float)MathHelper.Clamp(X + Math.Sign(currentDirection) * Clock.ElapsedFrameTime * base_speed * dashModifier, 0, 1); - } - - public void AddToStack(DrawableHitObject fruit, Vector2 absolutePosition) - { - fruit.RelativePositionAxes = Axes.None; - fruit.Position = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0); - - fruit.Anchor = Anchor.TopCentre; - fruit.Origin = Anchor.BottomCentre; - fruit.Scale *= 0.7f; - fruit.LifetimeEnd = double.MaxValue; - - float distance = fruit.DrawSize.X / 2 * fruit.Scale.X; - - while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance)) - { - fruit.X += RNG.Next(-5, 5); - fruit.Y -= RNG.Next(0, 5); - } - - caughtFruit.Add(fruit); - - if (((CatchBaseHit)fruit.HitObject).LastInCombo) - explode(); - } - - private void explode() - { - var fruit = caughtFruit.ToArray(); - - foreach (var f in fruit) - { - var originalX = f.X * Scale.X; - - if (ExplodingFruitTarget != null) - { - f.Anchor = Anchor.TopLeft; - f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget); - - caughtFruit.Remove(f); - - ExplodingFruitTarget.Add(f); - } - - f.MoveToY(f.Y - 50, 250, Easing.OutSine) - .Then() - .MoveToY(f.Y + 50, 500, Easing.InSine); - - f.MoveToX(f.X + originalX * 6, 1000); - f.FadeOut(750); - - f.Expire(); - } - } - } - } -} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 787825d482..718ae32a17 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -59,7 +59,7 @@ - + From 3338024c17b6febbf5aa47acc41b021e1f25c83c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2017 22:12:53 +0800 Subject: [PATCH 180/291] Fix incorrect whitespace --- osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index 45ab8ac300..5be07e94c0 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -12,8 +12,8 @@ namespace osu.Game.Rulesets.Catch.Tests { public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) { - } + protected override Beatmap CreateBeatmap() { var beatmap = new Beatmap(); From 37393ab2c946bfb236e7ae0514efcf895ffcec4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Oct 2017 22:24:22 +0800 Subject: [PATCH 181/291] Move brace --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 38f3273055..c4033b562d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -43,7 +43,8 @@ namespace osu.Game.Rulesets.Catch.UI { RelativeSizeAxes = Axes.Both, }, - catcherContainer = new Container { + catcherContainer = new Container + { RelativeSizeAxes = Axes.X, Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, From cf44868bcdd090d0b43313545b9e0c5646b42e5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 15:02:11 +0900 Subject: [PATCH 182/291] Give EditorScreen a Beatmap --- osu.Game/Screens/Edit/Editor.cs | 1 + osu.Game/Screens/Edit/Screens/EditorScreen.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8a11a50fd6..ca072ed73e 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -118,6 +118,7 @@ namespace osu.Game.Screens.Edit break; } + currentScreen.Beatmap.BindTo(Beatmap); screenContainer.Add(currentScreen); } diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index c456ad6a51..509c61a530 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -1,13 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; namespace osu.Game.Screens.Edit.Screens { public class EditorScreen : Container { + public readonly Bindable Beatmap = new Bindable(); + protected override Container Content => content; private readonly Container content; From 1a7e3fa09e4d51db6a30dfe7975538fc1277b824 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 19:21:08 +0900 Subject: [PATCH 183/291] Initial implementation of a test case which showcases waveforms --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 ++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 150 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseWaveform.cs diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs new file mode 100644 index 0000000000..5f4e86fb92 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -0,0 +1,149 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; + +namespace osu.Game.Tests.Visual +{ + internal class TestCaseWaveform : OsuTestCase + { + private readonly Bindable beatmapBacking = new Bindable(); + + private readonly List displays = new List(); + + public TestCaseWaveform() + { + MusicController mc; + FillFlowContainer flow; + Child = flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + mc = new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = 100, + State = Visibility.Visible + }, + } + }; + + for (int i = 1; i <= 16; i *= 2) + { + var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + + displays.Add(newDisplay); + + flow.Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 100, + Children = new Drawable[] + { + newDisplay, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.75f + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = $"Resolution: {(1f / i).ToString("0.00")}" + } + } + } + } + }); + } + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); + } + + private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + + private class WaveformDisplay : CompositeDrawable + { + private readonly int resolution; + + public WaveformDisplay(int resolution) + { + this.resolution = resolution; + } + + public void Display(Waveform waveform) + { + ClearInternal(); + + var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + + for (int i = 0; i < generated.Count; i++) + { + var point = generated[i]; + + // Left channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), + Colour = Color4.Red + }); + + if (waveform.Channels >= 2) + { + // Right channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.TopLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), + Colour = Color4.Green + }); + } + } + } + + private class NonInputBox : Box + { + public override bool HandleInput => false; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a8536bbc2..56490b6119 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -777,6 +777,7 @@ + From 319649f4465a45bc93c615d57ceb11ac36cd8460 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 21:19:38 +0900 Subject: [PATCH 184/291] Make TestCaseWaveform use a custom drawnode instead of boxes --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 128 +++++++++++++++++----- 1 file changed, 101 insertions(+), 27 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 5f4e86fb92..3f71e74a8d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -5,12 +5,19 @@ using System; using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; +using OpenTK.Graphics.ES30; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -92,51 +99,118 @@ namespace osu.Game.Tests.Visual private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); - private class WaveformDisplay : CompositeDrawable + private class WaveformDisplay : Drawable { + private List points; + private int channels; + + private Shader shader; + private readonly Texture texture; + private readonly int resolution; public WaveformDisplay(int resolution) { this.resolution = resolution; + + texture = Texture.WhitePixel; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } public void Display(Waveform waveform) { - ClearInternal(); + points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + channels = waveform.Channels; + Invalidate(Invalidation.DrawNode); + } - var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - for (int i = 0; i < generated.Count; i++) + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Points = points; + n.Channels = channels; + n.Size = DrawSize; + n.Shared = sharedData; + + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) { - var point = generated[i]; + base.Draw(vertexAction); - // Left channel - AddInternal(new NonInputBox - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), - Colour = Color4.Red - }); + if (Points == null || Points.Count == 0) + return; - if (waveform.Channels >= 2) + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) { - // Right channel - AddInternal(new NonInputBox + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) { - Anchor = Anchor.CentreLeft, - Origin = Anchor.TopLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), - Colour = Color4.Green - }); + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); } + + Shader.Unbind(); } } From 3eeb36cbd42f3cfa4b7b448e9c4170af4a346601 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 23:23:20 +0900 Subject: [PATCH 185/291] Remove now unused class --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 3f71e74a8d..2966728fb5 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -143,7 +143,6 @@ namespace osu.Game.Tests.Visual n.Size = DrawSize; n.Shared = sharedData; - base.ApplyDrawNode(node); } @@ -213,11 +212,6 @@ namespace osu.Game.Tests.Visual Shader.Unbind(); } } - - private class NonInputBox : Box - { - public override bool HandleInput => false; - } } } } From a37b10d51220b5f0df864cd8e503696eb669a0b6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:42:22 +0900 Subject: [PATCH 186/291] Make TestCaseWaveform use invalidations + remove some of the crud --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 69 +++++++++++++++-------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 2966728fb5..4df7ffe367 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -28,8 +28,6 @@ namespace osu.Game.Tests.Visual { private readonly Bindable beatmapBacking = new Bindable(); - private readonly List displays = new List(); - public TestCaseWaveform() { MusicController mc; @@ -53,9 +51,13 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + var newDisplay = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Resolution = 1f / i + }; - displays.Add(newDisplay); + newDisplay.Beatmap.BindTo(beatmapBacking); flow.Add(new Container { @@ -91,29 +93,21 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - beatmapBacking.BindTo(osuGame.Beatmap); - beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); - } - - private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); private class WaveformDisplay : Drawable { - private List points; - private int channels; + public readonly Bindable Beatmap = new Bindable(); + + private Waveform waveform; private Shader shader; private readonly Texture texture; - private readonly int resolution; - - public WaveformDisplay(int resolution) + public WaveformDisplay() { - this.resolution = resolution; - texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; } [BackgroundDependencyLoader] @@ -122,26 +116,51 @@ namespace osu.Game.Tests.Visual shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } - public void Display(Waveform waveform) + private float resolution = 1; + public float Resolution { - points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); - channels = waveform.Channels; - Invalidate(Invalidation.DrawNode); + get { return resolution; } + set + { + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } } - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + private Track lastQueriedTrack; + + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); protected override void ApplyDrawNode(DrawNode node) { var n = (WaveformDrawNode)node; n.Shader = shader; n.Texture = texture; - n.Points = points; - n.Channels = channels; n.Size = DrawSize; n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; base.ApplyDrawNode(node); } From 01c839eda7dfeb6f68edf6b6a442e956f6715c60 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:55:17 +0900 Subject: [PATCH 187/291] Move WaveformDisplay into separate class and add some commenting --- .../Edit/Screens/Compose/WaveformDisplay.cs | 168 ++++++++++++++++++ osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 +--------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 170 insertions(+), 148 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs new file mode 100644 index 0000000000..0f0c32ea0d --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -0,0 +1,168 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class WaveformDisplay : Drawable + { + /// + /// The beatmap which the audio waveform should be displayed for. + /// + /// + public readonly Bindable Beatmap = new Bindable(); + + private Shader shader; + private readonly Texture texture; + + public WaveformDisplay() + { + texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + } + + private float resolution = 1; + /// + /// Controls the amount of interpolation of the waveform into the width of this . + /// Points in the waveform are interpolated between 1 / pixels of this . + /// + /// + public float Resolution + { + get { return resolution; } + set + { + if (value < 0 || value > 1) + throw new ArgumentOutOfRangeException(nameof(value)); + + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } + } + + private Waveform waveform; + private Track lastQueriedTrack; + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } + + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Size = DrawSize; + n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + if (Points == null || Points.Count == 0) + return; + + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) + { + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) + { + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); + } + + Shader.Unbind(); + } + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4df7ffe367..0430185bf7 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -1,26 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; -using OpenTK.Graphics.ES30; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; namespace osu.Game.Tests.Visual { @@ -94,143 +85,5 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); - - private class WaveformDisplay : Drawable - { - public readonly Bindable Beatmap = new Bindable(); - - private Waveform waveform; - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - public float Resolution - { - get { return resolution; } - set - { - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Track lastQueriedTrack; - - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); - n.Channels = waveform.Channels; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56490b6119..f89810dfc1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -620,6 +620,7 @@ + From 80e984f72dea9361b6b2d53cb9bdbe42614412d2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:38 +0900 Subject: [PATCH 188/291] Update in-line with framework --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 0f0c32ea0d..a781e63fd9 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); n.Channels = waveform.Channels; base.ApplyDrawNode(node); From 81960c7b487d2a66b134ad9554d0a639153a2483 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:45 +0900 Subject: [PATCH 189/291] CI fixes --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 -- osu.Game/Tests/Visual/TestCaseWaveform.cs | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index a781e63fd9..236f6b6d47 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// /// The beatmap which the audio waveform should be displayed for. /// - /// public readonly Bindable Beatmap = new Bindable(); private Shader shader; @@ -46,7 +45,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// Controls the amount of interpolation of the waveform into the width of this . /// Points in the waveform are interpolated between 1 / pixels of this . /// - /// public float Resolution { get { return resolution; } diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 0430185bf7..eff4f5cdad 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -21,7 +21,6 @@ namespace osu.Game.Tests.Visual public TestCaseWaveform() { - MusicController mc; FillFlowContainer flow; Child = flow = new FillFlowContainer { @@ -30,7 +29,7 @@ namespace osu.Game.Tests.Visual Spacing = new Vector2(0, 10), Children = new Drawable[] { - mc = new MusicController + new MusicController { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -74,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i).ToString("0.00")}" + Text = $"Resolution: {(1f / i):0.00}" } } } From 5ca4a2d2c81600178816afb37778e40ce480f47c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:09:39 +0900 Subject: [PATCH 190/291] Add some nullchecks to WaveformDisplay --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 236f6b6d47..d1550117df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,8 +90,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); - n.Channels = waveform.Channels; + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); } From 357a4673373a3dd1e0fc1da0bc5b01e3ba998c7d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:24:19 +0900 Subject: [PATCH 191/291] Implement design mode --- osu.Game/Screens/Edit/Editor.cs | 4 ++ .../Screens/Edit/Screens/Design/Design.cs | 52 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 3 files changed, 57 insertions(+) create mode 100644 osu.Game/Screens/Edit/Screens/Design/Design.cs diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index ca072ed73e..036243e668 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,6 +14,7 @@ using OpenTK; using osu.Framework.Allocation; using osu.Game.Screens.Edit.Screens; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Design; namespace osu.Game.Screens.Edit { @@ -113,6 +114,9 @@ namespace osu.Game.Screens.Edit case EditorScreenMode.Compose: currentScreen = new Compose(); break; + case EditorScreenMode.Design: + currentScreen = new Design(); + break; default: currentScreen = new EditorScreen(); break; diff --git a/osu.Game/Screens/Edit/Screens/Design/Design.cs b/osu.Game/Screens/Edit/Screens/Design/Design.cs new file mode 100644 index 0000000000..e527d7dad9 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Design/Design.cs @@ -0,0 +1,52 @@ +// 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.Sprites; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Design +{ + internal class Design : EditorScreen + { + public Design() + { + Add(new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.35f + }, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.5f + }, + new Container + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding(20), + Child = new OsuSpriteText { Text = "Design screen" } + } + } + } + } + }); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a8536bbc2..39fd968763 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -618,6 +618,7 @@ + From e2824d4732c1c177619820ae231223991520ff5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:26:26 +0900 Subject: [PATCH 192/291] Reduce harshness of scale for now Though I don't feel like we should worry about this much just yet until we have actual designs and can see how it looks. It's very well possible that we use different transitions here... --- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index 509c61a530..152c00a48d 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -28,14 +28,14 @@ namespace osu.Game.Screens.Edit.Screens { base.LoadComplete(); - this.ScaleTo(0.5f).FadeTo(0) + this.ScaleTo(0.75f).FadeTo(0) .Then() .ScaleTo(1f, 500, Easing.OutQuint).FadeTo(1f, 250, Easing.OutQuint); } public void Exit() { - this.ScaleTo(1.5f, 500).FadeOut(250).Expire(); + this.ScaleTo(1.25f, 500).FadeOut(250).Expire(); } } } From 34eede0d04dd887e472846163027d36b52f1bbc5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:36:55 +0900 Subject: [PATCH 193/291] Re-namespace EditorScreenMode --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 2 +- .../Edit/Menus/ScreenSelectionTabControl.cs | 14 +------------- .../Screens/Edit/Screens/EditorScreenMode.cs | 19 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/EditorScreenMode.cs diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 4c9b3c84b3..34a96b0a6e 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; -using System; +using osu.Game.Screens.Edit.Screens; namespace osu.Game.Screens.Edit.Menus { diff --git a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs index 652ef1d61f..f5e47464ae 100644 --- a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs +++ b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs @@ -9,8 +9,8 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Edit.Screens; using OpenTK; -using System.ComponentModel; namespace osu.Game.Screens.Edit.Menus { @@ -70,16 +70,4 @@ namespace osu.Game.Screens.Edit.Menus } } } - - public enum EditorScreenMode - { - [Description("compose")] - Compose, - [Description("design")] - Design, - [Description("timing")] - Timing, - [Description("song")] - SongSetup - } } diff --git a/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs b/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs new file mode 100644 index 0000000000..6489bb305b --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.ComponentModel; + +namespace osu.Game.Screens.Edit.Screens +{ + public enum EditorScreenMode + { + [Description("compose")] + Compose, + [Description("design")] + Design, + [Description("timing")] + Timing, + [Description("song")] + SongSetup + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 39fd968763..f1ba54cba3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -613,6 +613,7 @@ + From 8a52fdc8fa5abc503c6399cb214a7c0d97a39092 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:37:17 +0900 Subject: [PATCH 194/291] Use a bindable for the current screen in EditorMenuBar Replaces the current Action. --- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 036243e668..4fca38a6c6 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -96,7 +96,7 @@ namespace osu.Game.Screens.Edit }; timeline.Beatmap.BindTo(Beatmap); - menuBar.ModeChanged += onModeChanged; + menuBar.Mode.ValueChanged += onModeChanged; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 34a96b0a6e..a4348b4489 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -11,16 +11,14 @@ using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Configuration; using osu.Game.Screens.Edit.Screens; namespace osu.Game.Screens.Edit.Menus { public class EditorMenuBar : OsuMenu { - /// - /// Invaoked when the selected mode has changed. - /// - public event Action ModeChanged; + public readonly Bindable Mode = new Bindable(); private readonly ScreenSelectionTabControl tabControl; @@ -42,7 +40,7 @@ namespace osu.Game.Screens.Edit.Menus } }); - tabControl.Current.ValueChanged += v => ModeChanged?.Invoke(v); + tabControl.Current.BindTo(Mode); } protected override void LoadComplete() From 1377f73b460b90f7fd4037b51536cb36a7fff92f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:29 +0900 Subject: [PATCH 195/291] Multiply resolution before clamping --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index d1550117df..e11cd667e6 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); From ea4545299386900ba257dadcb25f7a0960901884 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:46 +0900 Subject: [PATCH 196/291] Allow resolution > 1 --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index e11cd667e6..3856558a32 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose get { return resolution; } set { - if (value < 0 || value > 1) + if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); if (resolution == value) From 8427bb44d18759b516865d49fd648327e3d14c99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:10:01 +0900 Subject: [PATCH 197/291] Implement basic layout for the compose screen ScrollableTimeline --- .../Screens/Compose/ScrollableTimeline.cs | 143 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 46 ++++++ osu.Game/osu.Game.csproj | 2 + 3 files changed, 191 insertions(+) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs create mode 100644 osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs new file mode 100644 index 0000000000..31d207a152 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -0,0 +1,143 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class ScrollableTimeline : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly Container timelineContainer; + private readonly WaveformDisplay waveform; + + public ScrollableTimeline() + { + Masking = true; + CornerRadius = 5; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 25 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + new OsuCheckbox { LabelText = "Hit Objects" }, + new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Waveform" } + } + } + } + }, + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 30), + Children = new[] + { + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_plus, + Colour = OsuColour.FromHex("555") + }, + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_minus, + Colour = OsuColour.FromHex("555") + }, + } + } + } + }, + timelineContainer = new Container + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + waveform = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("081a84") + // Resolution = 0.33f, + } + } + } + } + } + }; + + waveform.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return false; + + waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); + return true; + } + + protected override void Update() + { + base.Update(); + + timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs new file mode 100644 index 0000000000..714c7b5d50 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseEditorComposeTimeline : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(WaveformDisplay) }; + + private readonly ScrollableTimeline timeline; + + public TestCaseEditorComposeTimeline() + { + Children = new Drawable[] + { + new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + State = Visibility.Visible + }, + timeline = new ScrollableTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1000, 100) + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + timeline.Beatmap.BindTo(osuGame.Beatmap); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fde38848f1..d9c98e9b92 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -622,6 +622,7 @@ + @@ -748,6 +749,7 @@ + From e9bc5dbd0f5e18cb0520596303cf021acc3f6c5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 23:35:20 +0900 Subject: [PATCH 198/291] Include framework commits --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 9d142a8e00..bcd92492a9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9d142a8e009794dfee828392e36025d08577131d +Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde From 22a59d753b8fdb873a095ec77f67ee458c5b1d09 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 5 Oct 2017 04:38:13 +0300 Subject: [PATCH 199/291] Make all the overlays IStateful --- .../Play/BreaksOverlay/ArrowsOverlay.cs | 26 +++++---- .../Play/BreaksOverlay/BreakOverlay.cs | 17 +++--- .../Play/BreaksOverlay/InfoContainer.cs | 55 +++++++++++-------- .../Play/BreaksOverlay/LetterboxOverlay.cs | 9 ++- .../BreaksOverlay/RemainingTimeCounter.cs | 9 ++- 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 9d729826de..111ed61fd3 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -5,11 +5,15 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using OpenTK; using osu.Game.Graphics.Containers; +using System; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Screens.Play.BreaksOverlay { - public class ArrowsOverlay : Container + public class ArrowsOverlay : VisibilityContainer { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private const int glow_icon_size = 60; private const int glow_icon_blur_sigma = 10; private const float glow_icon_final_offset = 0.22f; @@ -79,22 +83,22 @@ namespace osu.Game.Screens.Play.BreaksOverlay }; } - public void Show(double fadeDuration) + protected override void PopIn() { - leftGlowIcon.MoveToX(-glow_icon_final_offset, fadeDuration, Easing.OutQuint); - rightGlowIcon.MoveToX(glow_icon_final_offset, fadeDuration, Easing.OutQuint); + leftGlowIcon.MoveToX(-glow_icon_final_offset, fade_duration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_final_offset, fade_duration, Easing.OutQuint); - leftBlurredIcon.MoveToX(-blurred_icon_final_offset, fadeDuration, Easing.OutQuint); - rightBlurredIcon.MoveToX(blurred_icon_final_offset, fadeDuration, Easing.OutQuint); + leftBlurredIcon.MoveToX(-blurred_icon_final_offset, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_final_offset, fade_duration, Easing.OutQuint); } - public void Hide(double fadeDuration) + protected override void PopOut() { - leftGlowIcon.MoveToX(-glow_icon_offscreen_offset, fadeDuration, Easing.OutQuint); - rightGlowIcon.MoveToX(glow_icon_offscreen_offset, fadeDuration, Easing.OutQuint); + leftGlowIcon.MoveToX(-glow_icon_offscreen_offset, fade_duration, Easing.OutQuint); + rightGlowIcon.MoveToX(glow_icon_offscreen_offset, fade_duration, Easing.OutQuint); - leftBlurredIcon.MoveToX(-blurred_icon_offscreen_offset, fadeDuration, Easing.OutQuint); - rightBlurredIcon.MoveToX(blurred_icon_offscreen_offset, fadeDuration, Easing.OutQuint); + leftBlurredIcon.MoveToX(-blurred_icon_offscreen_offset, fade_duration, Easing.OutQuint); + rightBlurredIcon.MoveToX(blurred_icon_offscreen_offset, fade_duration, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 3b2335a455..1b0e04eac1 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay private void onBreakIn(BreakPeriod b) { if (letterboxing) - letterboxOverlay.FadeIn(fade_duration); + letterboxOverlay.Show(); remainingTimeBox .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) @@ -115,20 +115,19 @@ namespace osu.Game.Screens.Play.BreaksOverlay Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); - remainingTimeCounter.FadeIn(fade_duration); - - info.FadeIn(fade_duration); - arrowsOverlay.Show(fade_duration); + remainingTimeCounter.Show(); + info.Show(); + arrowsOverlay.Show(); } private void onBreakOut() { if (letterboxing) - letterboxOverlay.FadeOut(fade_duration); + letterboxOverlay.Hide(); - remainingTimeCounter.FadeOut(fade_duration); - info.FadeOut(fade_duration); - arrowsOverlay.Hide(fade_duration); + remainingTimeCounter.Hide(); + info.Hide(); + arrowsOverlay.Hide(); } public void BindProcessor(ScoreProcessor processor) diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 351dc66930..6a850d066d 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -1,16 +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 OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Scoring; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Screens.Play.BreaksOverlay { - public class InfoContainer : FillFlowContainer + public class InfoContainer : VisibilityContainer { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + public PercentageInfoLine AccuracyDisplay; public InfoLine RankDisplay; public InfoLine GradeDisplay; @@ -18,33 +22,38 @@ namespace osu.Game.Screens.Play.BreaksOverlay public InfoContainer() { AutoSizeAxes = Axes.Both; - Alpha = 0; - Direction = FillDirection.Vertical; - Spacing = new Vector2(5); - Children = new Drawable[] + Child = new FillFlowContainer { - new OsuSpriteText + Direction = FillDirection.Vertical, + Spacing = new Vector2(5), + Children = new Drawable[] { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "current progress".ToUpper(), - TextSize = 15, - Font = "Exo2.0-Black", - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new OsuSpriteText { - AccuracyDisplay = new PercentageInfoLine("Accuracy"), - RankDisplay = new InfoLine("Rank", @"#"), - GradeDisplay = new InfoLine("Grade"), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "current progress".ToUpper(), + TextSize = 15, + Font = "Exo2.0-Black", }, - } + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + AccuracyDisplay = new PercentageInfoLine("Accuracy"), + RankDisplay = new InfoLine("Rank", @"#"), + GradeDisplay = new InfoLine("Grade"), + }, + } + }, }; } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs index 1581c45c56..e0d3889673 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs @@ -1,16 +1,19 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Screens.Play.BreaksOverlay { - public class LetterboxOverlay : Container + public class LetterboxOverlay : VisibilityContainer { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; private const int height = 350; private static readonly Color4 transparent_black = new Color4(0, 0, 0, 0); @@ -18,7 +21,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay public LetterboxOverlay() { RelativeSizeAxes = Axes.Both; - Alpha = 0; Children = new Drawable[] { new Container @@ -59,5 +61,8 @@ namespace osu.Game.Screens.Play.BreaksOverlay } }; } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); } } diff --git a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs index c8b8b6a072..b5d77d0d02 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/RemainingTimeCounter.cs @@ -5,11 +5,14 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics; using System; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Screens.Play.BreaksOverlay { - public class RemainingTimeCounter : Container + public class RemainingTimeCounter : VisibilityContainer { + private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + private readonly OsuSpriteText counter; private int? previousSecond; @@ -21,7 +24,6 @@ namespace osu.Game.Screens.Play.BreaksOverlay public RemainingTimeCounter() { AutoSizeAxes = Axes.Both; - Alpha = 0; Child = counter = new OsuSpriteText { Anchor = Anchor.Centre, @@ -56,5 +58,8 @@ namespace osu.Game.Screens.Play.BreaksOverlay else isCounting = false; } } + + protected override void PopIn() => this.FadeIn(fade_duration); + protected override void PopOut() => this.FadeOut(fade_duration); } } From 20bf0502ab4cabe2e38561b75a92c5e0822b65d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Oct 2017 10:03:48 +0800 Subject: [PATCH 200/291] Use scheduling rather than raw transform delays --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 1b0e04eac1..4457eb56f8 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -93,12 +93,11 @@ namespace osu.Game.Screens.Play.BreaksOverlay if (!b.HasEffect) continue; - using (BeginAbsoluteSequence(b.StartTime, true)) + using (BeginAbsoluteSequence(b.StartTime)) { - onBreakIn(b); - - using (BeginDelayedSequence(b.Duration - fade_duration, true)) - onBreakOut(); + Schedule(() => onBreakIn(b)); + using (BeginDelayedSequence(b.Duration - fade_duration)) + Schedule(onBreakOut); } } } @@ -113,7 +112,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay .Then() .ResizeWidthTo(0, b.Duration - fade_duration); - Scheduler.AddDelayed(() => remainingTimeCounter.StartCounting(b.EndTime), b.StartTime - Clock.CurrentTime); + remainingTimeCounter.StartCounting(b.EndTime); remainingTimeCounter.Show(); info.Show(); From cc99678a963cf2f36e9affe900aa4346c93ff62a Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 5 Oct 2017 05:09:23 +0300 Subject: [PATCH 201/291] Remove useless usings --- osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs | 1 - osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs | 1 - osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs index 111ed61fd3..0b775d5c35 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/ArrowsOverlay.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using OpenTK; using osu.Game.Graphics.Containers; -using System; using osu.Game.Beatmaps.Timing; namespace osu.Game.Screens.Play.BreaksOverlay diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 6a850d066d..307828b665 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs index e0d3889673..9d5bc986e9 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/LetterboxOverlay.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.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; From cb0dbc6d9ef6671b80d947a0d9be2734cf901baf Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 5 Oct 2017 05:23:18 +0300 Subject: [PATCH 202/291] Fix shrinking bar lingering on the screen for too long --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 4457eb56f8..64521a7972 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay remainingTimeBox .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) .Then() - .ResizeWidthTo(0, b.Duration - fade_duration); + .ResizeWidthTo(0, b.Duration - fade_duration * 2); remainingTimeCounter.StartCounting(b.EndTime); From 5caca1d3283b8478b05f0df815c17aeb386da4a1 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 5 Oct 2017 05:27:52 +0300 Subject: [PATCH 203/291] Don't use '#' in RankDisplay for now --- osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs index 307828b665..1bf9b26cc9 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/InfoContainer.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay Children = new Drawable[] { AccuracyDisplay = new PercentageInfoLine("Accuracy"), - RankDisplay = new InfoLine("Rank", @"#"), + RankDisplay = new InfoLine("Rank"), GradeDisplay = new InfoLine("Grade"), }, } From 2bc8fe027b616e904c1b6958a7427104e88f6a84 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Thu, 5 Oct 2017 06:17:48 +0300 Subject: [PATCH 204/291] Extend the testcase to test short breaks --- osu.Game/Tests/Visual/TestCaseBreakOverlay.cs | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs index 074aa16934..206ca308cf 100644 --- a/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseBreakOverlay.cs @@ -20,11 +20,12 @@ namespace osu.Game.Tests.Visual Child = breakOverlay = new BreakOverlay(true); - AddStep("Add 2s break", () => startBreak(2000)); - AddStep("Add 5s break", () => startBreak(5000)); - AddStep("Add 10s break", () => startBreak(10000)); - AddStep("Add 15s break", () => startBreak(15000)); - AddStep("Add 2 breaks (2s each)", startMultipleBreaks); + AddStep("2s break", () => startBreak(2000)); + AddStep("5s break", () => startBreak(5000)); + AddStep("10s break", () => startBreak(10000)); + AddStep("15s break", () => startBreak(15000)); + AddStep("2s, 2s", startMultipleBreaks); + AddStep("0.5s, 0.7s, 1s, 2s", startAnotherMultipleBreaks); } private void startBreak(double duration) @@ -57,5 +58,34 @@ namespace osu.Game.Tests.Visual } }; } + + private void startAnotherMultipleBreaks() + { + double currentTime = Clock.CurrentTime; + + breakOverlay.Breaks = new List + { + new BreakPeriod // Duration is less than 650 - too short to appear + { + StartTime = currentTime, + EndTime = currentTime + 500, + }, + new BreakPeriod + { + StartTime = currentTime + 1500, + EndTime = currentTime + 2200, + }, + new BreakPeriod + { + StartTime = currentTime + 3200, + EndTime = currentTime + 4200, + }, + new BreakPeriod + { + StartTime = currentTime + 5200, + EndTime = currentTime + 7200, + } + }; + } } } \ No newline at end of file From 0a9d23b4bad1da2081f720a3227319d10bbd11df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:39 +0900 Subject: [PATCH 205/291] Update with framework changes (removal of WaveformDisplay) --- osu-framework | 2 +- .../Screens/Compose/BeatmapWaveformGraph.cs | 33 ++++ .../Edit/Screens/Compose/WaveformDisplay.cs | 166 ------------------ osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 36 insertions(+), 169 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs delete mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu-framework b/osu-framework index bcd92492a9..4019939ba9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde +Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs new file mode 100644 index 0000000000..ceabda5b16 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class BeatmapWaveformGraph : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly WaveformGraph graph; + + public BeatmapWaveformGraph() + { + InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; + Beatmap.ValueChanged += b => graph.Track = b.Track; + } + + /// + /// Gets or sets the . + /// + public float Resolution + { + get { return graph.Resolution; } + set { graph.Resolution = value; } + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs deleted file mode 100644 index 3856558a32..0000000000 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using OpenTK; -using osu.Framework.Allocation; -using osu.Framework.Audio.Track; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; -using osu.Framework.Graphics.Textures; -using osu.Game.Beatmaps; - -namespace osu.Game.Screens.Edit.Screens.Compose -{ - public class WaveformDisplay : Drawable - { - /// - /// The beatmap which the audio waveform should be displayed for. - /// - public readonly Bindable Beatmap = new Bindable(); - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - /// - /// Controls the amount of interpolation of the waveform into the width of this . - /// Points in the waveform are interpolated between 1 / pixels of this . - /// - public float Resolution - { - get { return resolution; } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value)); - - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Waveform waveform; - private Track lastQueriedTrack; - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); - n.Channels = waveform?.Channels ?? 0; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } -} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index eff4f5cdad..531005af10 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay + var newDisplay = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Resolution = 1f / i diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f89810dfc1..106e4bfc3b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,6 +266,7 @@ + @@ -620,7 +621,6 @@ - From 7926757898ea4b12579f6fae8abce00e89a754ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:49 +0900 Subject: [PATCH 206/291] Remove unneeded parens --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 531005af10..4a6e93c7bf 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i):0.00}" + Text = $"Resolution: {1f / i:0.00}" } } } From 134e1299bb4a71e219edfd7746df79fa33cdc888 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 19:23:58 +0800 Subject: [PATCH 207/291] Update spm value when spinner not active. --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 04bbd8b871..b36fe4287e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -112,20 +112,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); - if (rotations.Count > 0) - { - float rotationFrom = rotations.Peek(); - double timeFrom = times.Peek(); - while (Time.Current - times.Peek() > spm_count_duration) - { - rotationFrom = rotations.Dequeue(); - timeFrom = times.Dequeue(); - } - SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; - } } lastAngle = thisAngle; + if (rotations.Count > 0) + { + float rotationFrom = rotations.Peek(); + double timeFrom = times.Peek(); + while (Time.Current - times.Peek() > spm_count_duration) + { + rotationFrom = rotations.Dequeue(); + timeFrom = times.Dequeue(); + } + SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + } rotations.Enqueue(currentRotation); times.Enqueue(Time.Current); From 24187cc53a02442c7bf747f371ac7ff8e502ca5d Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 19:55:20 +0800 Subject: [PATCH 208/291] Move spm text out of scaled parts. --- .../Objects/Drawables/DrawableSpinner.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6b9e91d4f4..4bdb789471 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -99,24 +99,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Origin = Anchor.Centre, }, circleContainer.CreateProxy(), - spmText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Text = @"0", - Font = @"Venera", - TextSize = 24, - Y = 120 - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - Text = @"SPINS PER MINUTE", - Font = @"Venera", - TextSize = 12, - Y = 125 - }, ticks = new SpinnerTicks { Anchor = Anchor.Centre, @@ -124,6 +106,24 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }, } }, + spmText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24, + Y = 120 + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 125 + }, }; } From ee8746b848b82577f031365327db804dc63b39a7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 20:07:33 +0800 Subject: [PATCH 209/291] Fade in spm texts. --- .../Objects/Drawables/DrawableSpinner.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 4bdb789471..6a8976ea98 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -31,7 +31,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; - private readonly OsuSpriteText spmText; + private readonly OsuSpriteText spmText, spmLabel; + + private bool spmShown; private readonly SpriteIcon symbol; @@ -113,16 +115,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Text = @"0", Font = @"Venera", TextSize = 24, - Y = 120 + Y = 120, + Alpha = 0 }, - new OsuSpriteText + spmLabel = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, Text = @"SPINS PER MINUTE", Font = @"Venera", TextSize = 12, - Y = 125 + Y = 125, + Alpha = 0 }, }; } @@ -178,6 +182,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); + if (!spmShown && disc.Tracking) + { + spmShown = true; + spmText.FadeIn(TIME_FADEIN); + spmLabel.FadeIn(TIME_FADEIN); + } base.Update(); } From 29f9c8143df0c01786843caf5d158f98040b30ea Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 20:08:45 +0800 Subject: [PATCH 210/291] Use RotationAbsolute to calculate spm. --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index b36fe4287e..913305c6aa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -124,9 +124,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces rotationFrom = rotations.Dequeue(); timeFrom = times.Dequeue(); } - SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + SpinsPerMinute = (RotationAbsolute - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; } - rotations.Enqueue(currentRotation); + rotations.Enqueue(RotationAbsolute); times.Enqueue(Time.Current); if (Complete && updateCompleteTick()) From 96fcc095eb8461a5c0a30ba456e73ab2badd64bf Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 6 Oct 2017 04:49:16 +0300 Subject: [PATCH 211/291] Apply suggested shrinking bar changes --- .../Play/BreaksOverlay/BreakOverlay.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 64521a7972..ea24cffb30 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -33,6 +33,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay private readonly bool letterboxing; private readonly LetterboxOverlay letterboxOverlay; + private readonly Container remainingTimeAdjustmentBox; private readonly Container remainingTimeBox; private readonly RemainingTimeCounter remainingTimeCounter; private readonly InfoContainer info; @@ -50,15 +51,23 @@ namespace osu.Game.Screens.Play.BreaksOverlay Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - remainingTimeBox = new Container + remainingTimeAdjustmentBox = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Size = new Vector2(0, 8), - CornerRadius = 4, - Masking = true, - Child = new Box { RelativeSizeAxes = Axes.Both } + Width = 0, + Child = remainingTimeBox = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 8, + CornerRadius = 4, + Masking = true, + Child = new Box { RelativeSizeAxes = Axes.Both } + } }, remainingTimeCounter = new RemainingTimeCounter { @@ -107,10 +116,15 @@ namespace osu.Game.Screens.Play.BreaksOverlay if (letterboxing) letterboxOverlay.Show(); - remainingTimeBox + remainingTimeAdjustmentBox .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) + .Delay(b.Duration - fade_duration) + .ResizeWidthTo(0); + + remainingTimeBox + .ResizeWidthTo(0, b.Duration - fade_duration) .Then() - .ResizeWidthTo(0, b.Duration - fade_duration * 2); + .ResizeWidthTo(1); remainingTimeCounter.StartCounting(b.EndTime); From 95ac4e92658d448c07bfb29fdcdc7248d5876a12 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 6 Oct 2017 04:57:46 +0300 Subject: [PATCH 212/291] Remove useless using --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index ea24cffb30..f5062aa40f 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.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 OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 404c4917dc7689903e649c5dae150b2b8b11b819 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 6 Oct 2017 18:35:51 +0800 Subject: [PATCH 213/291] Use single queue for spinning record. --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 913305c6aa..8af7de88e4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -79,8 +79,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float currentRotation; public float RotationAbsolute; public double SpinsPerMinute; - private readonly Queue rotations = new Queue(); - private readonly Queue times = new Queue(); + + private struct RotationRecord + { + public float Rotation; + public double Time; + } + + private readonly Queue records = new Queue(); private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues private int completeTick; @@ -115,19 +121,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } lastAngle = thisAngle; - if (rotations.Count > 0) + if (records.Count > 0) { - float rotationFrom = rotations.Peek(); - double timeFrom = times.Peek(); - while (Time.Current - times.Peek() > spm_count_duration) - { - rotationFrom = rotations.Dequeue(); - timeFrom = times.Dequeue(); - } - SpinsPerMinute = (RotationAbsolute - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + var record = records.Peek(); + while (Time.Current - records.Peek().Time > spm_count_duration) + record = records.Dequeue(); + SpinsPerMinute = (RotationAbsolute - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } - rotations.Enqueue(RotationAbsolute); - times.Enqueue(Time.Current); + records.Enqueue(new RotationRecord { Rotation = RotationAbsolute, Time = Time.Current }); if (Complete && updateCompleteTick()) { From 3557737a18ae303f76adc8919654ed0f2d17e56e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Oct 2017 23:20:56 +0800 Subject: [PATCH 214/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5f19dd913d..ef889b4ec7 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5f19dd913dfc69013a3b9cf30ccfd9c44881a321 +Subproject commit ef889b4ec7e6175d52d64411c15f4f195fd16209 From 19c663da110cf62ceda4cf4df8f608c7f1917e41 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Oct 2017 23:41:49 +0800 Subject: [PATCH 215/291] Remove scale effect on editor screen switches --- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index 152c00a48d..ac248930d8 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -28,14 +28,14 @@ namespace osu.Game.Screens.Edit.Screens { base.LoadComplete(); - this.ScaleTo(0.75f).FadeTo(0) + this.FadeTo(0) .Then() - .ScaleTo(1f, 500, Easing.OutQuint).FadeTo(1f, 250, Easing.OutQuint); + .FadeTo(1f, 250, Easing.OutQuint); } public void Exit() { - this.ScaleTo(1.25f, 500).FadeOut(250).Expire(); + this.FadeOut(250).Expire(); } } } From fc99860f4eb60d5bbaca12771409bfb383997b9f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 00:48:31 +0900 Subject: [PATCH 216/291] Remove EditorMenuBarItem --- osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs | 15 --------------- osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs | 7 ++++--- osu.Game/osu.Game.csproj | 1 - 3 files changed, 4 insertions(+), 19 deletions(-) delete mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs deleted file mode 100644 index 201bc6e5c3..0000000000 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics.UserInterface; - -namespace osu.Game.Screens.Edit.Menus -{ - public class EditorMenuBarItem : MenuItem - { - public EditorMenuBarItem(string text) - : base(text) - { - } - } -} diff --git a/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs index b0c21b6b8c..0d0f2609ef 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorMenuBar.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; @@ -28,7 +29,7 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, Items = new[] { - new EditorMenuBarItem("File") + new MenuItem("File") { Items = new[] { @@ -55,7 +56,7 @@ namespace osu.Game.Tests.Visual new EditorMenuItem("Exit"), } }, - new EditorMenuBarItem("Timing") + new MenuItem("Timing") { Items = new[] { @@ -78,7 +79,7 @@ namespace osu.Game.Tests.Visual new EditorMenuItem("Set Current Position as Preview Point"), } }, - new EditorMenuBarItem("Testing") + new MenuItem("Testing") { Items = new[] { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 84d1ae56fc..ff5c492fc7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -623,7 +623,6 @@ - From a154ee3a8984b2c3a3106c0a88d45283feea4246 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 00:51:30 +0900 Subject: [PATCH 217/291] Add File -> Exit to editor menu --- osu.Game/Screens/Edit/Editor.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 4fca38a6c6..2756a163e7 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -12,6 +12,8 @@ using osu.Game.Screens.Edit.Menus; using osu.Game.Screens.Edit.Components.Timelines.Summary; using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Screens; using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Design; @@ -45,7 +47,17 @@ namespace osu.Game.Screens.Edit { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Items = new[] + { + new MenuItem("File") + { + Items = new[] + { + new EditorMenuItem("Exit", MenuItemType.Standard, Exit) + } + } + } } }, new Container From d3109a5950468c09bd13b2143815960b44018ea5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 00:59:14 +0900 Subject: [PATCH 218/291] Hook up BeatmapPanel "Edit" item --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 5 ++++- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 +++ osu.Game/Screens/Select/SongSelect.cs | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 9c62289bfa..d1682a392d 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -31,6 +31,8 @@ namespace osu.Game.Beatmaps.Drawables public Action HideDifficultyRequested; + public Action EditRequested; + public BeatmapSetHeader Header; public List BeatmapPanels; @@ -87,7 +89,8 @@ namespace osu.Game.Beatmaps.Drawables Alpha = 0, GainedSelection = panelGainedSelection, HideRequested = p => HideDifficultyRequested?.Invoke(p), - StartRequested = p => { StartRequested?.Invoke(p.Beatmap); }, + StartRequested = p => StartRequested?.Invoke(p.Beatmap), + EditRequested = p => EditRequested?.Invoke(p.Beatmap), RelativeSizeAxes = Axes.X, }).ToList(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index abd288baf2..c72f599955 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -177,6 +177,8 @@ namespace osu.Game.Screens.Select public Action RestoreRequested; + public Action EditRequested; + public Action HideDifficultyRequested; public void SelectNext(int direction = 1, bool skipDifficulties = true) @@ -347,6 +349,7 @@ namespace osu.Game.Screens.Select StartRequested = b => StartRequested?.Invoke(), DeleteRequested = b => DeleteRequested?.Invoke(b), RestoreHiddenRequested = s => RestoreRequested?.Invoke(s), + EditRequested = b => EditRequested?.Invoke(b), HideDifficultyRequested = b => HideDifficultyRequested?.Invoke(b), State = BeatmapGroupState.Collapsed }; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 836ed465c3..b11613634a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; +using osu.Game.Screens.Edit; using osu.Game.Screens.Select.Options; namespace osu.Game.Screens.Select @@ -108,6 +109,7 @@ namespace osu.Game.Screens.Select BeatmapsChanged = carouselBeatmapsLoaded, DeleteRequested = promptDelete, RestoreRequested = s => { foreach (var b in s.Beatmaps) manager.Restore(b); }, + EditRequested = editRequested, HideDifficultyRequested = b => manager.Hide(b), StartRequested = () => carouselRaisedStart(), }); @@ -195,6 +197,12 @@ namespace osu.Game.Screens.Select carousel.AllowSelection = !Beatmap.Disabled; } + private void editRequested(BeatmapInfo beatmap) + { + Beatmap.Value = manager.GetWorkingBeatmap(beatmap, Beatmap); + Push(new Editor()); + } + private void onBeatmapRestored(BeatmapInfo b) => carousel.UpdateBeatmap(b); private void onBeatmapHidden(BeatmapInfo b) => carousel.UpdateBeatmap(b); From 837d1ba12e6a83e4a5e10adca5d1e57bf664267a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 01:38:13 +0900 Subject: [PATCH 219/291] Remove rounded corners on the editor menu bar --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index a4348b4489..fdaac81c68 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Edit.Menus { RelativeSizeAxes = Axes.X; + MaskingContainer.CornerRadius = 0; ItemsContainer.Padding = new MarginPadding { Left = 100 }; BackgroundColour = OsuColour.FromHex("111"); From 38ae9d905e44c0a132046bbd2151f0c6847f2cb5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 01:42:45 +0900 Subject: [PATCH 220/291] Fix bindable binding to make the editor load a screen by default again --- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index fdaac81c68..17b2e64d8e 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -20,8 +20,6 @@ namespace osu.Game.Screens.Edit.Menus { public readonly Bindable Mode = new Bindable(); - private readonly ScreenSelectionTabControl tabControl; - public EditorMenuBar() : base(Direction.Horizontal, true) { @@ -31,6 +29,7 @@ namespace osu.Game.Screens.Edit.Menus ItemsContainer.Padding = new MarginPadding { Left = 100 }; BackgroundColour = OsuColour.FromHex("111"); + ScreenSelectionTabControl tabControl; AddRangeInternal(new Drawable[] { tabControl = new ScreenSelectionTabControl @@ -41,13 +40,13 @@ namespace osu.Game.Screens.Edit.Menus } }); - tabControl.Current.BindTo(Mode); + Mode.BindTo(tabControl.Current); } protected override void LoadComplete() { base.LoadComplete(); - tabControl.Current.TriggerChange(); + Mode.TriggerChange(); } protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); From d432ab7510072781da6b4f1cb7559e127ff67333 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 01:44:20 +0900 Subject: [PATCH 221/291] Reorder screen tab control items --- osu.Game/Screens/Edit/Screens/EditorScreenMode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs b/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs index 6489bb305b..578d888193 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreenMode.cs @@ -7,13 +7,13 @@ namespace osu.Game.Screens.Edit.Screens { public enum EditorScreenMode { + [Description("setup")] + SongSetup, [Description("compose")] Compose, [Description("design")] Design, [Description("timing")] Timing, - [Description("song")] - SongSetup } } From c0b394811ff00cab3d55f0ade5d6165a0c955fd0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 01:46:54 +0900 Subject: [PATCH 222/291] Make compose mode the default Hopefully we can keep this at a ScreenSelectionTabControl level, but it may need to be moved to the Editor at some point. I'm leaving that for a future change however, if it's needed. --- osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs index f5e47464ae..dae2e4b320 100644 --- a/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs +++ b/osu.Game/Screens/Edit/Menus/ScreenSelectionTabControl.cs @@ -33,6 +33,8 @@ namespace osu.Game.Screens.Edit.Menus Height = 1, Colour = Color4.White.Opacity(0.2f), }); + + Current.Value = EditorScreenMode.Compose; } [BackgroundDependencyLoader] From 10abaa866b06491d740c7649cf34311116bd855c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 7 Oct 2017 01:56:11 +0900 Subject: [PATCH 223/291] Put screens below the top and bottom bars of the editor --- osu.Game/Screens/Edit/Editor.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 2756a163e7..b47a3263b7 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -38,6 +38,17 @@ namespace osu.Game.Screens.Edit Children = new[] { + new Container + { + Name = "Screen container", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 40, Bottom = 60 }, + Child = screenContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true + } + }, new Container { Name = "Top bar", @@ -94,17 +105,6 @@ namespace osu.Game.Screens.Edit } } }, - new Container - { - Name = "Screen container", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 40, Bottom = 60 }, - Child = screenContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true - } - } }; timeline.Beatmap.BindTo(Beatmap); From 5a8b8dacbb99c6dfb17f702cd4aedf823bc85878 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 6 Oct 2017 21:00:23 +0200 Subject: [PATCH 224/291] move stuff thats duplicated in PreviewButton and DirectPanel to PlayButton --- osu.Game/Audio/AudioLoadWrapper.cs | 32 ------ osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 58 ++--------- osu.Game/Overlays/Direct/DirectGridPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 48 ++------- osu.Game/Overlays/Direct/PlayButton.cs | 99 +++++++++++++++++-- osu.Game/Overlays/DirectOverlay.cs | 22 ++--- osu.Game/osu.Game.csproj | 1 - 8 files changed, 117 insertions(+), 147 deletions(-) delete mode 100644 osu.Game/Audio/AudioLoadWrapper.cs diff --git a/osu.Game/Audio/AudioLoadWrapper.cs b/osu.Game/Audio/AudioLoadWrapper.cs deleted file mode 100644 index 67836d1690..0000000000 --- a/osu.Game/Audio/AudioLoadWrapper.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Track; -using osu.Framework.Graphics; - -namespace osu.Game.Audio -{ - public class AudioLoadWrapper : Drawable - { - private readonly string preview; - - public Track Preview; - - public AudioLoadWrapper(string preview) - { - this.preview = preview; - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - if (!string.IsNullOrEmpty(preview)) - { - Preview = audio.Track.Get(preview); - Preview.Volume.Value = 0.5; - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index ea49963f67..2fe2edaf1d 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -27,21 +27,13 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box bg, progress; private readonly PlayButton playButton; - private Track preview; - private readonly Bindable playing = new Bindable(); + private Track preview => playButton.Preview; + private Bindable playing => playButton.Playing; - private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet { - get { return beatmapSet; } - set - { - if (value == beatmapSet) return; - beatmapSet = value; - - playing.Value = false; - preview = null; - } + get { return playButton.SetInfo; } + set { playButton.SetInfo = value; } } public PreviewButton() @@ -69,7 +61,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - playButton = new PlayButton(playing) + playButton = new PlayButton() { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -78,7 +70,7 @@ namespace osu.Game.Overlays.BeatmapSet }; Action = () => playing.Value = !playing.Value; - playing.ValueChanged += updatePlayingState; + playing.ValueChanged += newValue => progress.FadeTo(newValue ? 1 : 0, 100); } [BackgroundDependencyLoader] @@ -94,11 +86,6 @@ namespace osu.Game.Overlays.BeatmapSet if (playing.Value && preview != null) { progress.Width = (float)(preview.CurrentTime / preview.Length); - if (preview.HasCompleted) - { - playing.Value = false; - preview = null; - } } } @@ -119,38 +106,5 @@ namespace osu.Game.Overlays.BeatmapSet bg.FadeColour(Color4.Black.Opacity(0.25f), 100); base.OnHoverLost(state); } - - private void updatePlayingState(bool newValue) - { - if (preview == null) - { - playButton.Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet.OnlineInfo.Preview) - { - OnLoadComplete = d => - { - playButton.Loading = false; - - preview = (d as AudioLoadWrapper)?.Preview; - playing.TriggerChange(); - }, - }); - } - else - { - if (newValue) - { - progress.FadeIn(100); - - preview.Seek(0); - preview.Start(); - } - else - { - progress.FadeOut(100); - preview.Stop(); - } - } - } } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 10611cd5be..7464ee7fb8 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -192,7 +192,7 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, - playButton = new PlayButton(PreviewPlaying) + playButton = new PlayButton(SetInfo) { Margin = new MarginPadding { Top = 5, Left = 10 }, Size = new Vector2(30), diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 7f5fa3e3f0..5889a1bc12 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.Direct Spacing = new Vector2(10, 0), Children = new Drawable[] { - playButton = new PlayButton(PreviewPlaying) + playButton = new PlayButton(SetInfo) { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 2195fc9ce7..eaabb0b539 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -41,10 +41,9 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; private BeatmapSetOverlay beatmapSetOverlay; - private Container audioWrapper; - protected Track Preview; - public readonly Bindable PreviewPlaying = new Bindable(); + public Track Preview => PlayButton.Preview; + public Bindable PreviewPlaying => PlayButton.Playing; protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } @@ -87,7 +86,6 @@ namespace osu.Game.Overlays.Direct EdgeEffect = edgeEffectNormal, Children = new[] { - audioWrapper = new Container(), // temporary blackness until the actual background loads. BlackBackground = new Box { @@ -112,39 +110,6 @@ namespace osu.Game.Overlays.Direct if (downloadRequest != null) attachDownload(downloadRequest); - - PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); - PreviewPlaying.ValueChanged += setPlaying; - } - - private void setPlaying(bool newValue) - { - if (newValue) - { - if(Preview == null) - { - PlayButton.Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") - { - OnLoadComplete = d => - { - PlayButton.Loading = false; - Preview = (d as AudioLoadWrapper)?.Preview; - PreviewPlaying.TriggerChange(); - }, - }); - } - else - { - Preview.Seek(0); - Preview.Start(); - } - } - else - { - Preview?.Stop(); - } } protected override void Update() @@ -154,11 +119,6 @@ namespace osu.Game.Overlays.Direct if (PreviewPlaying && Preview != null) { PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length); - if (Preview.HasCompleted) - { - PreviewPlaying.Value = false; - Preview = null; - } } } @@ -184,6 +144,7 @@ namespace osu.Game.Overlays.Direct protected override bool OnClick(InputState state) { ShowInformation(); + PreviewPlaying.Value = false; return true; } @@ -244,6 +205,9 @@ namespace osu.Game.Overlays.Direct { base.LoadComplete(); this.FadeInFromZero(200, Easing.Out); + + PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint); + PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint); } protected List GetDifficultyIcons() diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 0405049c6a..dea6b1568d 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -3,10 +3,14 @@ using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -14,11 +18,28 @@ namespace osu.Game.Overlays.Direct { public class PlayButton : Container { - private readonly Bindable playing; + public readonly Bindable Playing = new Bindable(); + public Track Preview { get; private set; } + + private BeatmapSetInfo setInfo; + public BeatmapSetInfo SetInfo + { + get { return setInfo; } + set + { + if (value == setInfo) return; + setInfo = value; + + Playing.Value = false; + Preview = null; + } + } private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; + private Container audioWrapper; + private const float transition_duration = 500; private bool loading; @@ -41,11 +62,12 @@ namespace osu.Game.Overlays.Direct } } - public PlayButton(Bindable playing) + public PlayButton(BeatmapSetInfo setInfo = null) { - this.playing = playing; + this.SetInfo = setInfo; AddRange(new Drawable[] { + audioWrapper = new Container(), icon = new SpriteIcon { Anchor = Anchor.Centre, @@ -57,9 +79,10 @@ namespace osu.Game.Overlays.Direct loadingAnimation = new LoadingAnimation(), }); - playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; + Playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; + Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); - playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + Playing.ValueChanged += updatePreviewTrack; } [BackgroundDependencyLoader] @@ -70,7 +93,7 @@ namespace osu.Game.Overlays.Direct protected override bool OnClick(InputState state) { - playing.Value = !playing.Value; + Playing.Value = !Playing.Value; return true; } @@ -82,9 +105,71 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!playing.Value) + if(!Playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } + + protected override void Update() + { + base.Update(); + + if(Preview?.HasCompleted ?? false) + { + Playing.Value = false; + Preview = null; + } + } + + private void updatePreviewTrack(bool newValue) + { + if (newValue) + { + if (Preview == null) + { + Loading = true; + audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") + { + OnLoadComplete = d => + { + Loading = false; + Preview = (d as AudioLoadWrapper)?.Preview; + Playing.TriggerChange(); + }, + }); + } + else + { + Preview.Seek(0); + Preview.Start(); + } + } + else + { + Preview?.Stop(); + } + } + + private class AudioLoadWrapper : Drawable + { + private readonly string preview; + + public Track Preview; + + public AudioLoadWrapper(string preview) + { + this.preview = preview; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + if (!string.IsNullOrEmpty(preview)) + { + Preview = audio.Track.Get(preview); + Preview.Volume.Value = 0.5; + } + } + } } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9d79e87b1d..71dc558b26 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -230,21 +230,21 @@ namespace osu.Game.Overlays }) }; - foreach (DirectPanel panel in newPanels.Children) - panel.PreviewPlaying.ValueChanged += newValue => - { - if (newValue) - { - if (playing != null && playing != panel) - playing.PreviewPlaying.Value = false; - playing = panel; - } - }; - LoadComponentAsync(newPanels, p => { if (panels != null) ScrollFlow.Remove(panels); ScrollFlow.Add(panels = newPanels); + + foreach (DirectPanel panel in p.Children) + panel.PreviewPlaying.ValueChanged += newValue => + { + if (newValue) + { + if (playing != null && playing != panel) + playing.PreviewPlaying.Value = false; + playing = panel; + } + }; }); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0b72e22d25..e374b7c274 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -238,7 +238,6 @@ - From f3ca6cc38756d3c2d121cb6a553bd72db37f5413 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 6 Oct 2017 21:06:37 +0200 Subject: [PATCH 225/291] remove redundant stuff --- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 5 +---- osu.Game/Overlays/Direct/DirectPanel.cs | 1 - osu.Game/Overlays/Direct/PlayButton.cs | 5 ++--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index 2fe2edaf1d..d040c89a91 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using OpenTK; using OpenTK.Graphics; -using osu.Game.Audio; using osu.Game.Overlays.Direct; using osu.Framework.Configuration; @@ -23,7 +22,6 @@ namespace osu.Game.Overlays.BeatmapSet { private const float transition_duration = 500; - private readonly Container audioWrapper; private readonly Box bg, progress; private readonly PlayButton playButton; @@ -42,7 +40,6 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - audioWrapper = new Container(), bg = new Box { RelativeSizeAxes = Axes.Both, @@ -61,7 +58,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, }, }, - playButton = new PlayButton() + playButton = new PlayButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index eaabb0b539..ef89c0022b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -22,7 +22,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; using osu.Framework.Configuration; using osu.Framework.Audio.Track; -using osu.Game.Audio; namespace osu.Game.Overlays.Direct { diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index dea6b1568d..9ccce134d8 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -9,7 +9,6 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -38,7 +37,7 @@ namespace osu.Game.Overlays.Direct private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; - private Container audioWrapper; + private readonly Container audioWrapper; private const float transition_duration = 500; @@ -64,7 +63,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(BeatmapSetInfo setInfo = null) { - this.SetInfo = setInfo; + SetInfo = setInfo; AddRange(new Drawable[] { audioWrapper = new Container(), From a876ab9b90f87780a71ccc7ff48d77ea9b5530c4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 7 Oct 2017 15:31:42 +0800 Subject: [PATCH 226/291] Move spm counter to a seperated control. --- .../Objects/Drawables/DrawableSpinner.cs | 24 +++-------- .../Drawables/Pieces/SpinnerSpmCounter.cs | 42 +++++++++++++++++++ .../osu.Game.Rulesets.Osu.csproj | 1 + 3 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6a8976ea98..97c2594f69 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly SpinnerDisc disc; private readonly SpinnerTicks ticks; + private readonly SpinnerSpmCounter spmCounter; private readonly Container mainContainer; @@ -31,7 +32,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; - private readonly OsuSpriteText spmText, spmLabel; private bool spmShown; @@ -108,26 +108,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }, } }, - spmText = new OsuSpriteText + spmCounter = new SpinnerSpmCounter { Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Text = @"0", - Font = @"Venera", - TextSize = 24, + Origin = Anchor.Centre, Y = 120, Alpha = 0 - }, - spmLabel = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - Text = @"SPINS PER MINUTE", - Font = @"Venera", - TextSize = 12, - Y = 125, - Alpha = 0 - }, + } }; } @@ -185,8 +172,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!spmShown && disc.Tracking) { spmShown = true; - spmText.FadeIn(TIME_FADEIN); - spmLabel.FadeIn(TIME_FADEIN); + spmCounter.FadeIn(TIME_FADEIN); } base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs new file mode 100644 index 0000000000..17b2a813a5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces +{ + public class SpinnerSpmCounter : Container + { + private readonly OsuSpriteText spmText; + public SpinnerSpmCounter() + { + Children = new Drawable[] + { + spmText = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24 + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 30 + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 300000754c..6bad45b8ca 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -68,6 +68,7 @@ + From 09093013a7a0a639198741788906afaaff1e8b15 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 7 Oct 2017 15:42:10 +0800 Subject: [PATCH 227/291] Move spm calculation into counter. --- .../Objects/Drawables/DrawableSpinner.cs | 4 +- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 20 ---------- .../Drawables/Pieces/SpinnerSpmCounter.cs | 37 +++++++++++++++++-- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 97c2594f69..0fded6ec1a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.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 System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,7 +13,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Screens.Ranking; -using osu.Game.Graphics.Sprites; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -184,7 +182,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; - spmText.Text = Math.Truncate(disc.SpinsPerMinute).ToString(@"#0"); + spmCounter.SetRotation(disc.RotationAbsolute); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 8af7de88e4..ca75a61738 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -78,17 +77,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; public float RotationAbsolute; - public double SpinsPerMinute; - - private struct RotationRecord - { - public float Rotation; - public double Time; - } - - private readonly Queue records = new Queue(); - private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues - private int completeTick; private bool updateCompleteTick() => completeTick != (completeTick = (int)(RotationAbsolute / 360)); @@ -121,14 +109,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } lastAngle = thisAngle; - if (records.Count > 0) - { - var record = records.Peek(); - while (Time.Current - records.Peek().Time > spm_count_duration) - record = records.Dequeue(); - SpinsPerMinute = (RotationAbsolute - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; - } - records.Enqueue(new RotationRecord { Rotation = RotationAbsolute, Time = Time.Current }); if (Complete && updateCompleteTick()) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index 17b2a813a5..57ec516484 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -3,9 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -38,5 +35,39 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } }; } + + private double spm; + public double SpinsPerMinute + { + get { return spm; } + private set + { + if (value == spm) return; + spm = value; + spmText.Text = Math.Truncate(value).ToString(@"#0"); + } + } + + private struct RotationRecord + { + public float Rotation; + public double Time; + } + + private readonly Queue records = new Queue(); + private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues + + + public void SetRotation(float currentRotation) + { + if (records.Count > 0) + { + var record = records.Peek(); + while (Time.Current - records.Peek().Time > spm_count_duration) + record = records.Dequeue(); + SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; + } + records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current }); + } } } From 6c5c734ff1d07188812c75ad98bbb9e40fd396c1 Mon Sep 17 00:00:00 2001 From: Bang Sunghwan Date: Sun, 8 Oct 2017 09:42:09 +0900 Subject: [PATCH 228/291] Trim end of line Fix ArgumentOutOfRangeException when parsing http://osu.ppy.sh/osu/1004136 --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 21fee0f465..b4d5e8f13a 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,7 +611,7 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()) != null) + while ((line = stream.ReadLine()?.TrimEnd()) != null) { if (string.IsNullOrEmpty(line)) continue; From bd9f2db477d64aff156b1150949af5e1b6ec0ca2 Mon Sep 17 00:00:00 2001 From: Bang Sunghwan Date: Sun, 8 Oct 2017 17:30:21 +0900 Subject: [PATCH 229/291] Trim line --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index b4d5e8f13a..353959582b 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,7 +611,7 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()?.TrimEnd()) != null) + while ((line = stream.ReadLine()?.Trim()) != null) { if (string.IsNullOrEmpty(line)) continue; From 19b38983dffa148f09441a20185dd0f8b6f70521 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 17:18:11 +0900 Subject: [PATCH 230/291] Update in-line with framework --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 ++++++++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 14 ++++++++++++++ .../Edit/Screens/Compose/BeatmapWaveformGraph.cs | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 4019939ba9..38cf96c899 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 +Subproject commit 38cf96c8994ad41ae6aa86de6bfe09fd5fa9e1b6 diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..5fcdab11f8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -573,6 +573,16 @@ namespace osu.Game.Beatmaps } catch { return new TrackVirtual(); } } + + protected override Waveform GetWaveform() + { + try + { + var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); + return trackData == null ? new Waveform() : new Waveform(trackData); + } + catch { return new Waveform(); } + } } /// diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 277846ee80..959e71d48d 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -43,6 +43,7 @@ namespace osu.Game.Beatmaps protected abstract Beatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); + protected virtual Waveform GetWaveform() => new Waveform(); private Beatmap beatmap; private readonly object beatmapLock = new object(); @@ -96,6 +97,17 @@ namespace osu.Game.Beatmaps } } + private Waveform waveform; + private readonly object waveformLock = new object(); + public Waveform Waveform + { + get + { + lock (waveformLock) + return waveform ?? (waveform = GetWaveform()); + } + } + public bool TrackLoaded => track != null; public void TransferTo(WorkingBeatmap other) @@ -114,6 +126,8 @@ namespace osu.Game.Beatmaps { background?.Dispose(); background = null; + + waveform?.Dispose(); } public void DisposeTrack() diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs index ceabda5b16..f204c8c525 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose public BeatmapWaveformGraph() { InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; - Beatmap.ValueChanged += b => graph.Track = b.Track; + Beatmap.ValueChanged += b => graph.Waveform = b.Waveform; } /// From 222d0c86942416d2999f217a2a1b1ada26189c64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 17:52:48 +0900 Subject: [PATCH 231/291] Fix visual regressions in MedalOverlay --- osu.Game/Overlays/MedalOverlay.cs | 2 +- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 9 ++++++--- osu.Game/Tests/Visual/TestCaseMedalOverlay.cs | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index 880b607e78..776f2ffadb 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -159,7 +159,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, }); } diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 3ac8af7b2b..ea51471199 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -90,6 +90,7 @@ namespace osu.Game.Overlays.MedalSplash }, description = new TextFlowContainer { + TextAnchor = Anchor.TopCentre, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, @@ -115,15 +116,16 @@ namespace osu.Game.Overlays.MedalSplash medalSprite.Texture = textures.Get(medal.ImageUrl); medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow"); description.Colour = colours.BlueLight; - - unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10); - infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } protected override void LoadComplete() { base.LoadComplete(); + updateState(); + + unlocked.Position = new Vector2(0f, medalContainer.DrawSize.Y / 2 + 10); + infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } public DisplayState State @@ -172,6 +174,7 @@ namespace osu.Game.Overlays.MedalSplash this.ScaleTo(scale_when_full, duration, Easing.OutExpo); this.MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, Easing.OutExpo); + unlocked.Show(); name.FadeInFromZero(duration + 100); description.FadeInFromZero(duration * 2); break; diff --git a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs index fecf37538b..9a26eefd63 100644 --- a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs @@ -1,7 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Game.Overlays; +using osu.Game.Overlays.MedalSplash; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -10,6 +13,12 @@ namespace osu.Game.Tests.Visual { public override string Description => @"medal get!"; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MedalOverlay), + typeof(DrawableMedal), + }; + public TestCaseMedalOverlay() { AddStep(@"display", () => From 29c2a2979852f00ddafbf1d58560a681c2a2ea78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 18:47:12 +0900 Subject: [PATCH 232/291] Fix trimming too early in OsuLegacyDecoder crashing storyboards --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 353959582b..a70faf5be6 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,9 +611,9 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()?.Trim()) != null) + while ((line = stream.ReadLine()) != null) { - if (string.IsNullOrEmpty(line)) + if (string.IsNullOrEmpty(line.Trim())) continue; if (line.StartsWith("//")) @@ -679,10 +679,12 @@ namespace osu.Game.Beatmaps.Formats private KeyValuePair splitKeyVal(string line, char separator) { + var split = line.Trim().Split(separator); + return new KeyValuePair ( - line.Remove(line.IndexOf(separator)).Trim(), - line.Substring(line.IndexOf(separator) + 1).Trim() + split[0].Trim(), + split.Length > 1 ? split[1].Trim() : string.Empty ); } From 26215b448898a49af66749a8e4bbafe36aa45818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 19:42:55 +0900 Subject: [PATCH 233/291] Create an abstract base class for drawable catch objects --- .../Drawable/DrawableCatchHitObject.cs | 50 +++++++++++ .../Objects/Drawable/DrawableFruit.cs | 82 +++++-------------- .../osu.Game.Rulesets.Catch.csproj | 1 + 3 files changed, 72 insertions(+), 61 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs new file mode 100644 index 0000000000..fbb93e51a7 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject + { + protected DrawableCatchHitObject(CatchBaseHit hitObject) + : base(hitObject) + { + Origin = Anchor.Centre; + RelativePositionAxes = Axes.Both; + X = hitObject.X; + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + } + + public Func CheckPosition; + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (timeOffset > 0) + AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); + } + + private const float preempt = 1000; + + protected override void UpdateState(ArmedState state) + { + using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + { + // animation + this.FadeIn(200); + } + + switch (state) + { + case ArmedState.Miss: + using (BeginAbsoluteSequence(HitObject.StartTime, true)) + this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index e0c9f0c028..8e2618c64c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -1,72 +1,29 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableScrollingHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } - - public DrawableFruit(CatchBaseHit h) : base(h) { - Origin = Anchor.Centre; Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); - - RelativePositionAxes = Axes.Both; - X = h.X; - AccentColour = HitObject.ComboColour; - Masking = false; - - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } - public Func CheckPosition; - [BackgroundDependencyLoader] private void load() { @@ -115,28 +72,31 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } - private const float preempt = 1000; - - protected override void CheckForJudgements(bool userTriggered, double timeOffset) + private class Pulp : Circle, IHasAccentColour { - if (timeOffset > 0) - AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); - } - - protected override void UpdateState(ArmedState state) - { - using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + public Pulp() { - // animation - this.FadeIn(200); + Size = new Vector2(pulp_size); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); } - switch (state) + private Color4 accentColour; + public Color4 AccentColour { - case ArmedState.Miss: - using (BeginAbsoluteSequence(HitObject.StartTime, true)) - this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); - break; + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } } } } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 718ae32a17..f614ec647f 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -50,6 +50,7 @@ + From d5892cf54e7632ddfb7f410aeff1123f1a4bc4fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 20:17:05 +0900 Subject: [PATCH 234/291] Add a bool to specify whether judgements should be visible for certain DrawableHitObjects --- .../Objects/Drawables/DrawableSliderTick.cs | 2 ++ osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 +++ .../Objects/Drawables/DrawableDrumRollTick.cs | 2 ++ osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 53b3427fc4..8a96640b1e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override bool RemoveWhenNotAlive => false; + public override bool DisplayJudgement => false; + public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick) { this.sliderTick = sliderTick; diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 1bb4e8493b..89f6a4e255 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -91,6 +91,9 @@ namespace osu.Game.Rulesets.Osu.UI var osuJudgement = (OsuJudgement)judgement; var osuObject = (OsuHitObject)judgedObject.HitObject; + if (!judgedObject.DisplayJudgement) + return; + DrawableOsuJudgement explosion = new DrawableOsuJudgement(osuJudgement) { Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 8ac67ba0a6..e662f61bbe 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } + public override bool DisplayJudgement => false; + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index d9a216bbfc..136da8a532 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -221,7 +221,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - if (judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) + if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) { judgementContainer.Add(new DrawableTaikoJudgement(judgedObject, judgement) { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 7a26a53c2a..bcd6734af6 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -25,6 +25,11 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public virtual Color4 AccentColour { get; set; } = Color4.Gray; + /// + /// Whether a visible judgement should be displayed when this representation is hit. + /// + public virtual bool DisplayJudgement => true; + protected DrawableHitObject(HitObject hitObject) { HitObject = hitObject; From d1f02538cbc764175532d66318a4083c95a63a4c Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 9 Oct 2017 21:12:04 +0300 Subject: [PATCH 235/291] Add tooltip to username in the profile overlay --- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index d6a86fe714..742e865140 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using System.Diagnostics; using System.Globalization; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Profile { @@ -119,7 +120,7 @@ namespace osu.Game.Overlays.Profile } } }, - new LinkFlowContainer.LinkText + new LinkFlowContainer.BrowserLinkText { Text = user.Username, Url = $@"https://osu.ppy.sh/users/{user.Id}", @@ -539,6 +540,11 @@ namespace osu.Game.Overlays.Profile hoverColour = colours.Yellow; } } + + public class BrowserLinkText : LinkText, IHasTooltip + { + public string TooltipText => "View Profile in Browser"; + } } } } From 074a1db4a1969f64f29035be9340df947a710eac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 12:45:27 +0900 Subject: [PATCH 236/291] Implement scrolling and better zoom --- .../Screens/Compose/ScrollableTimeline.cs | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 7b2b52a239..5fc47958e2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -17,8 +17,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public readonly Bindable Beatmap = new Bindable(); - private readonly Container timelineContainer; - private readonly BeatmapWaveformGraph waveform; + private readonly ScrollingTimelineContainer timelineContainer; public ScrollableTimeline() { @@ -104,33 +103,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose } } }, - timelineContainer = new Container - { - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("081a84") - // Resolution = 0.33f, - } - } - } + timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y } } } }; - waveform.Beatmap.BindTo(Beatmap); - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return false; - - waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); - return true; + timelineContainer.Beatmap.BindTo(Beatmap); } protected override void Update() @@ -139,5 +117,49 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } + + private class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + + float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); + float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + + float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); + float scrollPos = newAbsoluteTarget - mousePos; + + Content.ResizeWidthTo(newSize); + ScrollTo(scrollPos, false); + + return true; + } + } } } From 166194e6b6f587c04cd0132a08dafab703416542 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:09:26 +0900 Subject: [PATCH 237/291] Further logic simplification --- .../Screens/Compose/ScrollableTimeline.cs | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 5fc47958e2..b5445883ab 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -142,20 +143,60 @@ namespace osu.Game.Screens.Edit.Screens.Compose graph.Beatmap.BindTo(Beatmap); } + private float minZoom = 1; + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + } + } + + private float maxZoom = 30; + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + } + } + + private float zoom = 1; + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); - float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + Zoom += state.Mouse.WheelDelta; - float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); - float scrollPos = newAbsoluteTarget - mousePos; - - Content.ResizeWidthTo(newSize); + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; ScrollTo(scrollPos, false); return true; From 1cf8c0284a3503c09c0f486c5d6b12f0f937f5ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:22:32 +0900 Subject: [PATCH 238/291] Re-namespace a few classes --- .../{ => Timeline}/BeatmapWaveformGraph.cs | 2 +- .../{ => Timeline}/ScrollableTimeline.cs | 86 +------------ .../Timeline/ScrollingTimelineContainer.cs | 113 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 3 +- osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 + osu.Game/osu.Game.csproj | 5 +- 6 files changed, 121 insertions(+), 89 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/BeatmapWaveformGraph.cs (91%) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/ScrollableTimeline.cs (63%) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs similarity index 91% rename from osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs index f204c8c525..5acee675e8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class BeatmapWaveformGraph : CompositeDrawable { diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs similarity index 63% rename from osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index b5445883ab..5999241f61 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -12,7 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollableTimeline : CompositeDrawable { @@ -118,89 +118,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } - - private class ScrollingTimelineContainer : ScrollContainer - { - public readonly Bindable Beatmap = new Bindable(); - - private readonly BeatmapWaveformGraph graph; - - public ScrollingTimelineContainer() - : base(Direction.Horizontal) - { - Masking = true; - - Add(graph = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, - }); - - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - - graph.Beatmap.BindTo(Beatmap); - } - - private float minZoom = 1; - public float MinZoom - { - get { return minZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (minZoom == value) - return; - minZoom = value; - } - } - - private float maxZoom = 30; - public float MaxZoom - { - get { return maxZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (maxZoom == value) - return; - maxZoom = value; - } - } - - private float zoom = 1; - public float Zoom - { - get { return zoom; } - set - { - value = MathHelper.Clamp(value, MinZoom, MaxZoom); - if (zoom == value) - return; - zoom = value; - - Content.ResizeWidthTo(Zoom); - } - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - - Zoom += state.Mouse.WheelDelta; - - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - - return true; - } - } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs new file mode 100644 index 0000000000..f4795452d5 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + internal class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + private float minZoom = 1; + /// + /// The minimum zoom level allowed. + /// + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float maxZoom = 30; + /// + /// The maximum zoom level allowed. + /// + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float zoom = 1; + /// + /// The current zoom level. + /// + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + + Zoom += state.Mouse.WheelDelta; + + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; + ScrollTo(scrollPos, false); + + return true; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 4ec3b8c661..40d617d2ea 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -9,12 +9,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4a6e93c7bf..c87be7e4b8 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b1d410ba50..321c2df4b5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,7 +266,7 @@ - + @@ -630,7 +630,8 @@ - + + From 9cb9151811526690b5c6b31391cb4e7f728f8f0c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 16:00:11 +0900 Subject: [PATCH 239/291] Move origin + anchor outside of ctor --- osu.Game/Graphics/UserInterface/IconButton.cs | 3 --- osu.Game/Overlays/MusicController.cs | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 1808dc4b6c..956fac279f 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -38,9 +38,6 @@ namespace osu.Game.Graphics.UserInterface { AutoSizeAxes = Axes.Both; - Origin = Anchor.Centre; - Anchor = Anchor.Centre; - Children = new Drawable[] { content = new Container diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 64d0d628f0..a99ce89a36 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -161,11 +161,15 @@ namespace osu.Game.Overlays { prevButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Action = prev, Icon = FontAwesome.fa_step_backward, }, playButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), Action = play, @@ -173,6 +177,8 @@ namespace osu.Game.Overlays }, nextButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Action = next, Icon = FontAwesome.fa_step_forward, }, From b306eaca6e40f83a83bd25476c5a81f403d7cb83 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 16:39:23 +0900 Subject: [PATCH 240/291] Move mania tests to correct namespace --- .../{Testing => Tests}/TestCaseManiaHitObjects.cs | 2 +- .../{Testing => Tests}/TestCaseManiaPlayfield.cs | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game.Rulesets.Mania/{Testing => Tests}/TestCaseManiaHitObjects.cs (96%) rename osu.Game.Rulesets.Mania/{Testing => Tests}/TestCaseManiaPlayfield.cs (96%) diff --git a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs similarity index 96% rename from osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs rename to osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs index a5568b7f6d..4230171288 100644 --- a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Visual; using OpenTK; using OpenTK.Graphics; -namespace osu.Game.Rulesets.Mania.Testing +namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] internal class TestCaseManiaHitObjects : OsuTestCase diff --git a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs similarity index 96% rename from osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs rename to osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs index 4b68334efb..c1de273a1b 100644 --- a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Tests.Visual; -namespace osu.Game.Rulesets.Mania.Testing +namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] internal class TestCaseManiaPlayfield : OsuTestCase diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index fa8b9d35aa..967f23bfd3 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -80,8 +80,8 @@ - - + + From d7fb59ee0e84c8583b6808b1ae3e1824ffbea624 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 17:20:23 +0900 Subject: [PATCH 241/291] Expose colours of IconButton --- osu.Game/Graphics/UserInterface/IconButton.cs | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 956fac279f..9f3f5096a2 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -15,9 +15,10 @@ namespace osu.Game.Graphics.UserInterface { public class IconButton : OsuClickableContainer { - private readonly SpriteIcon icon; - private readonly Box hover; - private readonly Container content; + private const float button_size = 30; + + public Color4 FlashColour; + public Color4 NormalColour; public FontAwesome Icon { @@ -25,15 +26,28 @@ namespace osu.Game.Graphics.UserInterface set { icon.Icon = value; } } - private const float button_size = 30; - private Color4 flashColour; - public Vector2 IconScale { get { return icon.Scale; } set { icon.Scale = value; } } + public Vector2 ButtonSize + { + get { return content.Size; } + set { content.Size = value; } + } + + public Color4 HoverColour + { + get { return hover.Colour; } + set { hover.Colour = value; } + } + + private readonly Container content; + private readonly SpriteIcon icon; + private readonly Box hover; + public IconButton() { AutoSizeAxes = Axes.Both; @@ -45,7 +59,6 @@ namespace osu.Game.Graphics.UserInterface Origin = Anchor.Centre, Anchor = Anchor.Centre, Size = new Vector2(button_size), - CornerRadius = 5, Masking = true, EdgeEffect = new EdgeEffectParameters @@ -75,8 +88,8 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - hover.Colour = colours.Yellow.Opacity(0.6f); - flashColour = colours.Yellow; + HoverColour = colours.Yellow.Opacity(0.6f); + FlashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } @@ -95,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(InputState state) { - hover.FlashColour(flashColour, 800, Easing.OutQuint); + hover.FlashColour(FlashColour, 800, Easing.OutQuint); return base.OnClick(state); } From bbd1a7059e0785b5693cce921205fcbec4c5ae6a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 17:25:39 +0900 Subject: [PATCH 242/291] xmldoc + hook up IconColour --- osu.Game/Graphics/UserInterface/IconButton.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 9f3f5096a2..5e5bfad662 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -17,27 +17,51 @@ namespace osu.Game.Graphics.UserInterface { private const float button_size = 30; + /// + /// The colour that should be flashed when the is clicked. + /// public Color4 FlashColour; - public Color4 NormalColour; + /// + /// The icon colour. This does not affect . + /// + public Color4 IconColour + { + get { return icon.Colour; } + set { icon.Colour = value; } + } + + /// + /// The icon. + /// public FontAwesome Icon { get { return icon.Icon; } set { icon.Icon = value; } } + /// + /// The icon scale. This does not affect . + /// public Vector2 IconScale { get { return icon.Scale; } set { icon.Scale = value; } } + /// + /// The size of the while it is not being pressed. + /// public Vector2 ButtonSize { get { return content.Size; } set { content.Size = value; } } + /// + /// The background colour of the while it is hovered. + /// + /// public Color4 HoverColour { get { return hover.Colour; } From 44141a38b8579cc0e5a9571ad60dac1bf8ba6ff5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:04:41 +0900 Subject: [PATCH 243/291] Make it possible to change colours before load() --- osu.Game/Graphics/UserInterface/IconButton.cs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 5e5bfad662..099423938a 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -17,10 +17,15 @@ namespace osu.Game.Graphics.UserInterface { private const float button_size = 30; + private Color4? flashColour; /// /// The colour that should be flashed when the is clicked. /// - public Color4 FlashColour; + public Color4 FlashColour + { + get { return flashColour ?? Color4.White; } + set { flashColour = value; } + } /// /// The icon colour. This does not affect . @@ -31,6 +36,20 @@ namespace osu.Game.Graphics.UserInterface set { icon.Colour = value; } } + private Color4? hoverColour; + /// + /// The background colour of the while it is hovered. + /// + public Color4 HoverColour + { + get { return hoverColour ?? Color4.White; } + set + { + hoverColour = value; + hover.Colour = value; + } + } + /// /// The icon. /// @@ -58,16 +77,6 @@ namespace osu.Game.Graphics.UserInterface set { content.Size = value; } } - /// - /// The background colour of the while it is hovered. - /// - /// - public Color4 HoverColour - { - get { return hover.Colour; } - set { hover.Colour = value; } - } - private readonly Container content; private readonly SpriteIcon icon; private readonly Box hover; @@ -112,8 +121,11 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - HoverColour = colours.Yellow.Opacity(0.6f); - FlashColour = colours.Yellow; + if (hoverColour == null) + hoverColour = colours.Yellow.Opacity(0.6f); + + if (flashColour == null) + flashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } From 071b1b049cebedee6844a97d37cf7e150c6a5989 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:31:56 +0900 Subject: [PATCH 244/291] Fix properties not being set leading to colours not being set --- osu.Game/Graphics/UserInterface/IconButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 099423938a..d58f5797a3 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -122,10 +122,10 @@ namespace osu.Game.Graphics.UserInterface private void load(OsuColour colours) { if (hoverColour == null) - hoverColour = colours.Yellow.Opacity(0.6f); + HoverColour = colours.Yellow.Opacity(0.6f); if (flashColour == null) - flashColour = colours.Yellow; + FlashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } From c2f3c0e6df60ef5579867d631cef16996eba467a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:32:09 +0900 Subject: [PATCH 245/291] Add TestCaseIconButton to demonstrate IconButton usages --- osu.Game/Tests/Visual/TestCaseIconButton.cs | 110 ++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 111 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseIconButton.cs diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs new file mode 100644 index 0000000000..7fe2eb01f0 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseIconButton.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 OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseIconButton : OsuTestCase + { + public override string Description => "Various display modes of icon buttons"; + + public TestCaseIconButton() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Spacing = new Vector2(10, 10), + Children = new[] + { + new NamedIconButton("No change", new IconButton()), + new NamedIconButton("Green colours", new IconButton + { + IconColour = Color4.LightGreen, + FlashColour = Color4.DarkGreen, + HoverColour = Color4.Green + }), + new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), + new NamedIconButton("Unchanging size", new IconButton(), false) + } + }; + } + + private class NamedIconButton : Container + { + public NamedIconButton(string name, IconButton button, bool allowSizeChange = true) + { + AutoSizeAxes = Axes.Y; + Width = 200; + + Container iconContainer; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.5f, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = name + }, + new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.1f, + }, + iconContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = button + } + } + } + } + } + }; + + if (allowSizeChange) + iconContainer.AutoSizeAxes = Axes.Both; + else + { + iconContainer.RelativeSizeAxes = Axes.X; + iconContainer.Height = 30; + } + + button.Anchor = Anchor.Centre; + button.Origin = Anchor.Centre; + button.Icon = FontAwesome.fa_osu_osu_o; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ff5c492fc7..81f360f640 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -759,6 +759,7 @@ + From 8cea875f5fe830f654462d9ce24f057af8d04494 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:35:30 +0900 Subject: [PATCH 246/291] Remove unused using --- osu.Game/Tests/Visual/TestCaseIconButton.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs index 7fe2eb01f0..bec8f8314b 100644 --- a/osu.Game/Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -6,7 +6,6 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; From ad344eb719242da7cff0bbdbf7c7d667bd9e32a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 19:21:38 +0900 Subject: [PATCH 247/291] Use IsNullOrWhiteSpace instead of trimming --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index a70faf5be6..2cf080746f 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -613,7 +613,7 @@ namespace osu.Game.Beatmaps.Formats string line; while ((line = stream.ReadLine()) != null) { - if (string.IsNullOrEmpty(line.Trim())) + if (string.IsNullOrWhiteSpace(line)) continue; if (line.StartsWith("//")) From b8d2a04fe1031f61cb35a7788d4e3cf0f35d1b38 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 19:24:24 +0900 Subject: [PATCH 248/291] Only split beatmap lines twice --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 2cf080746f..2493dab08c 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -679,7 +679,7 @@ namespace osu.Game.Beatmaps.Formats private KeyValuePair splitKeyVal(string line, char separator) { - var split = line.Trim().Split(separator); + var split = line.Trim().Split(new[] { separator }, 2); return new KeyValuePair ( From 03fbf47bc2f1974a9518b36aa3921dfac055c332 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 16:34:01 +0900 Subject: [PATCH 249/291] Add juicy streams --- .../Beatmaps/CatchBeatmapConverter.cs | 30 ++++- .../Drawable/DrawableCatchHitObject.cs | 15 ++- .../Objects/Drawable/DrawableDroplet.cs | 32 +++++ .../Objects/Drawable/DrawableFruit.cs | 40 +----- .../Objects/Drawable/DrawableJuiceStream.cs | 59 ++++++++ .../Objects/Drawable/Pieces/Pulp.cs | 40 ++++++ .../Objects/JuiceStream.cs | 126 ++++++++++++++++++ .../Tests/TestCaseCatchPlayer.cs | 12 -- .../Tests/TestCaseCatchStacker.cs | 27 ++++ osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +- .../UI/CatchRulesetContainer.cs | 9 +- .../osu.Game.Rulesets.Catch.csproj | 10 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 2 + 13 files changed, 346 insertions(+), 62 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/JuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 2efb0c0707..b3ff1acb02 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -5,9 +5,9 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; using System; +using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -17,14 +17,36 @@ namespace osu.Game.Rulesets.Catch.Beatmaps protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap) { - if (!(obj is IHasXPosition)) + var curveData = obj as IHasCurve; + var positionData = obj as IHasPosition; + var comboData = obj as IHasCombo; + + if (positionData == null) yield break; + if (curveData != null) + { + yield return new JuiceStream + { + StartTime = obj.StartTime, + Samples = obj.Samples, + ControlPoints = curveData.ControlPoints, + CurveType = curveData.CurveType, + Distance = curveData.Distance, + RepeatSamples = curveData.RepeatSamples, + RepeatCount = curveData.RepeatCount, + X = positionData.X / CatchPlayfield.BASE_WIDTH, + NewCombo = comboData?.NewCombo ?? false + }; + + yield break; + } + yield return new Fruit { StartTime = obj.StartTime, - NewCombo = (obj as IHasCombo)?.NewCombo ?? false, - X = ((IHasXPosition)obj).X / OsuPlayfield.BASE_SIZE.X + NewCombo = comboData?.NewCombo ?? false, + X = positionData.X / CatchPlayfield.BASE_WIDTH }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index fbb93e51a7..bb2df401cb 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -3,12 +3,23 @@ using System; using osu.Framework.Graphics; -using osu.Framework.MathUtils; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable { + public abstract class DrawableCatchHitObject : DrawableCatchHitObject + where TObject : CatchBaseHit + { + public new TObject HitObject; + + protected DrawableCatchHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } + } + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject { protected DrawableCatchHitObject(CatchBaseHit hitObject) @@ -17,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + Y = (float)HitObject.StartTime; } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs new file mode 100644 index 0000000000..fdb8c3e1e5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableDroplet : DrawableCatchHitObject + { + public DrawableDroplet(Droplet h) + : base(h) + { + Size = new Vector2(Pulp.PULP_SIZE); + + AccentColour = Color4.Green; + Masking = false; + } + + [BackgroundDependencyLoader] + private void load() + { + Child = new Pulp + { + AccentColour = AccentColour, + Scale = new Vector2(0.6f), + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 8e2618c64c..336647cbb9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -2,26 +2,26 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableCatchHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - public DrawableFruit(CatchBaseHit h) + public DrawableFruit(Fruit h) : base(h) { Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; + + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] @@ -71,33 +71,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } }; } - - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs new file mode 100644 index 0000000000..162fe05fc5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using OpenTK; +using OpenTK.Graphics; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableJuiceStream : DrawableCatchHitObject + { + private readonly Container dropletContainer; + + public DrawableJuiceStream(JuiceStream s) : base(s) + { + RelativeSizeAxes = Axes.Both; + Height = (float)HitObject.Duration; + + Child = dropletContainer = new Container + { + RelativeSizeAxes = Axes.Both, + RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), + RelativeChildSize = new Vector2(1, (float)HitObject.Duration) + }; + + var start = new DrawableFruit(new Fruit + { + ComboColour = Color4.Blue, + StartTime = s.StartTime, + X = s.X, + }); + + AddNested(start); + + var end = new DrawableFruit(new Fruit + { + ComboColour = Color4.Red, + StartTime = s.EndTime, + X = s.EndX, + }); + + AddNested(end); + + foreach (var tick in s.Ticks) + { + var droplet = new DrawableDroplet(tick); + AddNested(droplet); + } + } + + protected override void AddNested(DrawableHitObject h) + { + dropletContainer.Add(h); + base.AddNested(h); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs new file mode 100644 index 0000000000..6a19bfa69a --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -0,0 +1,40 @@ +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces +{ + public class Pulp : Circle, IHasAccentColour + { + public const float PULP_SIZE = 20; + + public Pulp() + { + Size = new Vector2(PULP_SIZE); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); + } + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs new file mode 100644 index 0000000000..5213d67225 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -0,0 +1,126 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class JuiceStream : CatchBaseHit, IHasCurve + { + /// + /// Scoring distance with a speed-adjusted beat length of 1 second. + /// + private const float base_scoring_distance = 100; + + public readonly SliderCurve Curve = new SliderCurve(); + + public int RepeatCount { get; set; } = 1; + + public double Velocity; + public double TickDistance; + + public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaults(controlPointInfo, difficulty); + + TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); + DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); + + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; + + Velocity = scoringDistance / timingPoint.BeatLength; + TickDistance = scoringDistance / difficulty.SliderTickRate; + } + + public IEnumerable Ticks + { + get + { + if (TickDistance == 0) yield break; + + var length = Curve.Distance; + var tickDistance = Math.Min(TickDistance, length); + var repeatDuration = length / Velocity; + + var minDistanceFromEnd = Velocity * 0.01; + + // temporary + while (tickDistance > 10) tickDistance /= 2; + + for (var repeat = 0; repeat < RepeatCount; repeat++) + { + var repeatStartTime = StartTime + repeat * repeatDuration; + var reversed = repeat % 2 == 1; + + for (var d = tickDistance; d <= length; d += tickDistance) + { + if (d > length - minDistanceFromEnd) + break; + + var distanceProgress = d / length; + var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + + yield return new Droplet + { + StartTime = repeatStartTime + timeProgress * repeatDuration, + X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }; + } + } + } + } + + public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity; + + public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH; + + public double Duration => EndTime - StartTime; + + public double Distance + { + get { return Curve.Distance; } + set { Curve.Distance = value; } + } + + public List ControlPoints + { + get { return Curve.ControlPoints; } + set { Curve.ControlPoints = value; } + } + + public List RepeatSamples { get; set; } = new List(); + + public CurveType CurveType + { + get { return Curve.CurveType; } + set { Curve.CurveType = value; } + } + + public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress)); + + public double ProgressAt(double progress) + { + double p = progress * RepeatCount % 1; + if (RepeatAt(progress) % 2 == 1) + p = 1 - p; + return p; + } + + public int RepeatAt(double progress) => (int)(progress * RepeatCount); + } +} diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index 5be07e94c0..25c095426f 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Tests { @@ -13,15 +11,5 @@ namespace osu.Game.Rulesets.Catch.Tests public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) { } - - protected override Beatmap CreateBeatmap() - { - var beatmap = new Beatmap(); - - for (int i = 0; i < 256; i++) - beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); - - return beatmap; - } } } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs new file mode 100644 index 0000000000..7c3bb2bfd8 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Tests +{ + [TestFixture] + public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer + { + public TestCaseCatchStacker() : base(typeof(CatchRuleset)) + { + } + + protected override Beatmap CreateBeatmap() + { + var beatmap = new Beatmap(); + + for (int i = 0; i < 256; i++) + beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); + + return beatmap; + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index c4033b562d..4d7af0f2b6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchPlayfield : ScrollingPlayfield { + public static readonly float BASE_WIDTH = 512; + protected override Container Content => content; private readonly Container content; @@ -28,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI Reversed.Value = true; - Size = new Vector2(1); - Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.UI base.Add(h); - var fruit = (DrawableFruit)h; + var fruit = (DrawableCatchHitObject)h; fruit.CheckPosition = CheckIfWeCanCatch; } diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 8a6ef71996..92912eb177 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -32,8 +32,13 @@ namespace osu.Game.Rulesets.Catch.UI protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { - if (h is Fruit) - return new DrawableFruit(h); + var fruit = h as Fruit; + if (fruit != null) + return new DrawableFruit(fruit); + + var stream = h as JuiceStream; + if (stream != null) + return new DrawableJuiceStream(stream); return null; } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index f614ec647f..906b7d663a 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -51,6 +51,10 @@ + + + + @@ -59,6 +63,7 @@ + @@ -80,11 +85,6 @@ osu.Framework False - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - False - {2a66dd92-adb1-4994-89e2-c94e04acda0d} osu.Game diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index 8bf85e498c..f920f97790 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; + public double Scale = 1; + public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; From e4f915e5af0f888a24884a8510eb2fead96a6357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 20:22:57 +0900 Subject: [PATCH 250/291] Fix scoring simulation not supporting juice --- .../Scoring/CatchScoreProcessor.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 16756e65f1..66a5636b74 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -21,6 +21,19 @@ namespace osu.Game.Rulesets.Catch.Scoring { foreach (var obj in beatmap.HitObjects) { + var stream = obj as JuiceStream; + + if (stream != null) + { + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + foreach (var unused in stream.Ticks) + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + continue; + } + var fruit = obj as Fruit; if (fruit != null) From 1fc16693d65c45cf5d84f2f478299a75b0b44ab4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 11:20:44 +0900 Subject: [PATCH 251/291] Formatting --- .../Objects/Drawables/Pieces/SpinnerSpmCounter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index 57ec516484..c079d3343b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -12,6 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public class SpinnerSpmCounter : Container { private readonly OsuSpriteText spmText; + public SpinnerSpmCounter() { Children = new Drawable[] @@ -37,6 +38,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } private double spm; + public double SpinsPerMinute { get { return spm; } @@ -57,7 +59,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Queue records = new Queue(); private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues - public void SetRotation(float currentRotation) { if (records.Count > 0) @@ -67,6 +68,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces record = records.Dequeue(); SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } + records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current }); } } From e76961a93287de7ca383ae911b0eb9d68e86bc3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 11:23:02 +0900 Subject: [PATCH 252/291] Remove unnecessary bool --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 0fded6ec1a..054a2067ec 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -31,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly CirclePiece circle; private readonly GlowPiece glow; - private bool spmShown; - private readonly SpriteIcon symbol; private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c"); @@ -167,11 +165,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); - if (!spmShown && disc.Tracking) - { - spmShown = true; + if (!spmCounter.IsPresent && disc.Tracking) spmCounter.FadeIn(TIME_FADEIN); - } base.Update(); } From b6cfc49b0676d7ae02ba7b3e11e80f5e5dd9de67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 12:41:17 +0900 Subject: [PATCH 253/291] Improve resilience of beatmap import test Fixes this happening https://ci.appveyor.com/project/peppy/osu/build/master-4694/tests --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 35bebf2d4f..a0c8fc48a5 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -118,15 +118,19 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1)."); IEnumerable resultBeatmaps = null; + IEnumerable resultBeatmapSet = null; //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout); - var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First(); + waitForOrAssert(() => (resultBeatmapSet = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Count() == 1, + @"BeatmapSet did not import to the database in allocated time", timeout); - Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(), - $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count})."); + var set = resultBeatmapSet.First(); + + waitForOrAssert(() => set.Beatmaps.Count == resultBeatmaps.Count(), + $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).", timeout); foreach (BeatmapInfo b in resultBeatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); From bf6ab77b0eaa77d5bb548685cbdc3a51f1fb4598 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 13:37:10 +0900 Subject: [PATCH 254/291] Always use live queries to ensure waiting asserts actually get dynamic data --- .../Beatmaps/IO/ImportBeatmapTest.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index a0c8fc48a5..cd9e765e7f 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -117,22 +117,27 @@ namespace osu.Game.Tests.Beatmaps.IO //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; - IEnumerable resultBeatmapSet = null; + Func> queryBeatmaps = () => store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0); + Func> queryBeatmapSets = () => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526); //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. - waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, + waitForOrAssert(() => queryBeatmaps().Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout); - waitForOrAssert(() => (resultBeatmapSet = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Count() == 1, + waitForOrAssert(() => queryBeatmapSets().Count() == 1, @"BeatmapSet did not import to the database in allocated time", timeout); - var set = resultBeatmapSet.First(); + int countBeatmapSetBeatmaps = 0; + int countBeatmaps = 0; - waitForOrAssert(() => set.Beatmaps.Count == resultBeatmaps.Count(), - $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).", timeout); + waitForOrAssert(() => + (countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count) == + (countBeatmaps = queryBeatmaps().Count()), + $@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).", timeout); - foreach (BeatmapInfo b in resultBeatmaps) + var set = queryBeatmapSets().First(); + + foreach (BeatmapInfo b in set.Beatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); Assert.IsTrue(set.Beatmaps.Count > 0); From cf7f3411fc6298bb2fb9e955977ffcd12bfeb77f Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 27 Sep 2017 20:27:01 +0800 Subject: [PATCH 255/291] Ignore filename case in BeatmapManager. Fixes #1295. --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..ce07b61ee4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -550,7 +550,7 @@ namespace osu.Game.Beatmaps catch { return null; } } - private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).FileInfo.StoragePath; + private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath; protected override Texture GetBackground() { From 76cf0e55a63b36018d2e1ed7f18a73f44013d93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:04:15 +0200 Subject: [PATCH 256/291] Fix capitalization of launch tasks --- .vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b8c026d891..5e761f118b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,7 @@ "console": "internalConsole" }, { - "name": "osu! (debug)", + "name": "osu! (Debug)", "windows": { "type": "clr" }, @@ -32,7 +32,7 @@ "console": "internalConsole" }, { - "name": "osu! (release)", + "name": "osu! (Release)", "windows": { "type": "clr" }, From 4922896636e9018db5ece66f97399f1e4d6bf161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:04:44 +0200 Subject: [PATCH 257/291] Mark release build task as "build" --- .vscode/tasks.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3db43ca9bb..35bf9e7a0e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -23,6 +23,7 @@ }, { "taskName": "Build (Release)", + "group": "build", "args": [ "/property:Configuration=Release" ], From f55b98079373b0ab1e28687660a51aa4735ed0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:05:00 +0200 Subject: [PATCH 258/291] Add launch task for visual tests in release mode --- .vscode/launch.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5e761f118b..d17dc33669 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,7 @@ { "version": "0.2.0", "configurations": [{ - "name": "osu! (VisualTests)", + "name": "osu! VisualTests (Debug)", "windows": { "type": "clr" }, @@ -17,6 +17,23 @@ "env": {}, "console": "internalConsole" }, + { + "name": "osu! VisualTests (Release)", + "windows": { + "type": "clr" + }, + "type": "mono", + "request": "launch", + "program": "${workspaceRoot}/osu.Game/bin/Release/osu!.exe", + "args": [ + "--tests" + ], + "cwd": "${workspaceRoot}", + "preLaunchTask": "Build (Release)", + "runtimeExecutable": null, + "env": {}, + "console": "internalConsole" + }, { "name": "osu! (Debug)", "windows": { From a6c54034feff7de349e5d4afe423c46ccecf349c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 17:38:21 +0900 Subject: [PATCH 259/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index ef889b4ec7..07e84f60b0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit ef889b4ec7e6175d52d64411c15f4f195fd16209 +Subproject commit 07e84f60b0d2ee443f366cb2e34bf25b680983dd From 1f1bdc6162eb972da2c7557305533f8c14a74cb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 18:18:06 +0900 Subject: [PATCH 260/291] Make juice streams interactive (and correctly positioned) --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 1 + .../Objects/Drawable/DrawableCatchHitObject.cs | 1 - osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 3 +++ osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 2 ++ .../Objects/Drawable/DrawableJuiceStream.cs | 4 ++++ osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +++++- 7 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index b3ff1acb02..0e4935aa7a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps yield return new Fruit { StartTime = obj.StartTime, + Samples = obj.Samples, NewCombo = comboData?.NewCombo ?? false, X = positionData.X / CatchPlayfield.BASE_WIDTH }; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index bb2df401cb..e057bf3d8e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -25,7 +25,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected DrawableCatchHitObject(CatchBaseHit hitObject) : base(hitObject) { - Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; Y = (float)HitObject.StartTime; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fdb8c3e1e5..aedef33cfd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; @@ -13,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableDroplet(Droplet h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(Pulp.PULP_SIZE); AccentColour = Color4.Green; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 336647cbb9..cffb2981bf 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableFruit(Fruit h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 162fe05fc5..19fe43a862 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; + X = 0; Child = dropletContainer = new Container { @@ -27,6 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var start = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Blue, StartTime = s.StartTime, X = s.X, @@ -36,6 +38,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var end = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Red, StartTime = s.EndTime, X = s.EndX, @@ -52,6 +55,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void AddNested(DrawableHitObject h) { + ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; dropletContainer.Add(h); base.AddNested(h); } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 5213d67225..fa19a6ff15 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; // temporary - while (tickDistance > 10) tickDistance /= 2; + while (tickDistance > 100) tickDistance /= 2; for (var repeat = 0; repeat < RepeatCount; repeat++) { diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4d7af0f2b6..987eef5e45 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -83,7 +83,11 @@ namespace osu.Game.Rulesets.Catch.UI if (judgement.IsHit) { Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; - Remove(judgedObject); + + // todo: don't do this + (judgedObject.Parent as Container)?.Remove(judgedObject); + (judgedObject.Parent as Container)?.Remove(judgedObject); + catcher.Add(judgedObject, screenPosition); } } From 1b732c799a5b5a9bb285e74cc145c94c45d1201d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 19:10:07 +0900 Subject: [PATCH 261/291] Make all juice nested objects from ticks --- .../Objects/Drawable/DrawableJuiceStream.cs | 29 +++++-------------- .../Objects/JuiceStream.cs | 25 ++++++++++++---- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19fe43a862..fe54397d18 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -26,30 +26,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable RelativeChildSize = new Vector2(1, (float)HitObject.Duration) }; - var start = new DrawableFruit(new Fruit + foreach (CatchBaseHit tick in s.Ticks) { - Samples = s.Samples, - ComboColour = Color4.Blue, - StartTime = s.StartTime, - X = s.X, - }); + Droplet droplet = tick as Droplet; + if (droplet != null) + AddNested(new DrawableDroplet(droplet)); - AddNested(start); - - var end = new DrawableFruit(new Fruit - { - Samples = s.Samples, - ComboColour = Color4.Red, - StartTime = s.EndTime, - X = s.EndX, - }); - - AddNested(end); - - foreach (var tick in s.Ticks) - { - var droplet = new DrawableDroplet(tick); - AddNested(droplet); + Fruit fruit = tick as Fruit; + if (fruit != null) + AddNested(new DrawableFruit(fruit)); } } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index fa19a6ff15..3ca0c8fbb6 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Objects TickDistance = scoringDistance / difficulty.SliderTickRate; } - public IEnumerable Ticks + public IEnumerable Ticks { get { @@ -53,8 +53,13 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - // temporary - while (tickDistance > 100) tickDistance /= 2; + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = StartTime, + X = X + }; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -66,8 +71,10 @@ namespace osu.Game.Rulesets.Catch.Objects if (d > length - minDistanceFromEnd) break; - var distanceProgress = d / length; - var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + var timeProgress = d / length; + var distanceProgress = reversed ? 1 - timeProgress : timeProgress; + + float tinyDroplet = 0; yield return new Droplet { @@ -81,6 +88,14 @@ namespace osu.Game.Rulesets.Catch.Objects })) }; } + + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = repeatStartTime + repeatDuration, + X = Curve.PositionAt(reversed ? 1 : 0).X + }; } } } From 0b282a49bd2b6f4145ea53d8738f4cec4486c6b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:11:29 +0900 Subject: [PATCH 262/291] Add tiny droplet support --- .../Objects/Drawable/DrawableDroplet.cs | 4 +- .../Objects/Drawable/DrawableJuiceStream.cs | 7 +++ .../Objects/JuiceStream.cs | 53 +++++++++++++++---- .../Objects/TinyDroplet.cs | 9 ++++ .../osu.Game.Rulesets.Catch.csproj | 1 + 5 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index aedef33cfd..fd48f11a3f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Size = new Vector2(Pulp.PULP_SIZE); - AccentColour = Color4.Green; + AccentColour = h.ComboColour; Masking = false; } @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = new Pulp { AccentColour = AccentColour, - Scale = new Vector2(0.6f), + Scale = new Vector2(0.8f), }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index fe54397d18..19abf243b3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -28,6 +28,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable foreach (CatchBaseHit tick in s.Ticks) { + TinyDroplet tiny = tick as TinyDroplet; + if (tiny != null) + { + AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); + continue; + } + Droplet droplet = tick as Droplet; if (droplet != null) AddNested(new DrawableDroplet(droplet)); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 3ca0c8fbb6..957a6e69ea 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -11,6 +11,8 @@ using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; +using osu.Framework.Lists; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -45,7 +47,10 @@ namespace osu.Game.Rulesets.Catch.Objects { get { - if (TickDistance == 0) yield break; + SortedList ticks = new SortedList((a, b) => a.StartTime.CompareTo(b.StartTime)); + + if (TickDistance == 0) + return ticks; var length = Curve.Distance; var tickDistance = Math.Min(TickDistance, length); @@ -53,13 +58,15 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - yield return new Fruit + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = StartTime, X = X - }; + }); + + double lastTickTime = StartTime; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -74,11 +81,11 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - float tinyDroplet = 0; - - yield return new Droplet + lastTickTime = repeatStartTime + timeProgress * repeatDuration; + ticks.Add(new Droplet { - StartTime = repeatStartTime + timeProgress * repeatDuration, + StartTime = lastTickTime, + ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, Samples = new SampleInfoList(Samples.Select(s => new SampleInfo { @@ -86,17 +93,41 @@ namespace osu.Game.Rulesets.Catch.Objects Name = @"slidertick", Volume = s.Volume })) - }; + }); } - yield return new Fruit + double tinyTickInterval = (tickDistance / length) * repeatDuration; + while (tinyTickInterval > 100) + tinyTickInterval /= 2; + + for (double t = 0; t < repeatDuration; t += tinyTickInterval) + { + double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration; + + ticks.Add(new TinyDroplet + { + StartTime = repeatStartTime + t, + ComboColour = ComboColour, + X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }); + } + + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = repeatStartTime + repeatDuration, - X = Curve.PositionAt(reversed ? 1 : 0).X - }; + X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH + }); } + + return ticks; } } diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs new file mode 100644 index 0000000000..231f3d5361 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs @@ -0,0 +1,9 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class TinyDroplet : Droplet + { + } +} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 906b7d663a..ba2c7a5f2e 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -61,6 +61,7 @@ + From 744d548738b92997f60b249413c3c431c25d6513 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:28:10 +0900 Subject: [PATCH 263/291] Add missing licence header --- osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 6a19bfa69a..00ddd365e3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -1,4 +1,7 @@ -using osu.Framework.Extensions.Color4Extensions; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 82b333740d5d65d637c86bfe57ab8735514f6c58 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 11 Oct 2017 15:20:23 +0300 Subject: [PATCH 264/291] Apply suggestions --- osu.Game/Overlays/Profile/ProfileHeader.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 742e865140..3814fdcc18 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -120,15 +120,13 @@ namespace osu.Game.Overlays.Profile } } }, - new LinkFlowContainer.BrowserLinkText + new LinkFlowContainer.ProfileLink(user) { - Text = user.Username, - Url = $@"https://osu.ppy.sh/users/{user.Id}", - TextSize = 30, - Font = @"Exo2.0-RegularItalic", Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Y = -48 + Y = -48, + TextSize = 30, + Font = @"Exo2.0-RegularItalic", }, countryFlag = new DrawableFlag(user.Country?.FlagName) { @@ -541,9 +539,15 @@ namespace osu.Game.Overlays.Profile } } - public class BrowserLinkText : LinkText, IHasTooltip + public class ProfileLink : LinkText, IHasTooltip { public string TooltipText => "View Profile in Browser"; + + public ProfileLink(User user) + { + Text = user.Username; + Url = $@"https://osu.ppy.sh/users/{user.Id}"; + } } } } From 4a4c01f2215f59be580e112c01919a412589f0a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:51:16 +0900 Subject: [PATCH 265/291] Fix CI problems --- .../Objects/Drawable/DrawableDroplet.cs | 1 - .../Objects/Drawable/DrawableJuiceStream.cs | 1 - osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 7 ++----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fd48f11a3f..2b2a8e7f8d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19abf243b3..afda91d0b4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -4,7 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; -using OpenTK.Graphics; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 957a6e69ea..f49799970d 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -12,7 +12,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; using osu.Framework.Lists; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -66,8 +65,6 @@ namespace osu.Game.Rulesets.Catch.Objects X = X }); - double lastTickTime = StartTime; - for (var repeat = 0; repeat < RepeatCount; repeat++) { var repeatStartTime = StartTime + repeat * repeatDuration; @@ -81,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - lastTickTime = repeatStartTime + timeProgress * repeatDuration; + var lastTickTime = repeatStartTime + timeProgress * repeatDuration; ticks.Add(new Droplet { StartTime = lastTickTime, @@ -96,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects }); } - double tinyTickInterval = (tickDistance / length) * repeatDuration; + double tinyTickInterval = tickDistance / length * repeatDuration; while (tinyTickInterval > 100) tinyTickInterval /= 2; From 6fbf52c3eb45a5ebcc48331efa882851c3cd4aa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:32:18 +0900 Subject: [PATCH 266/291] Remove unused usings --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 -- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 +- osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs | 1 - osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 5999241f61..c662341f20 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -1,13 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index f4795452d5..a64f139e5a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, + Depth = float.MaxValue }); Content.AutoSizeAxes = Axes.None; diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 40d617d2ea..00547145cd 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index c87be7e4b8..fc21b86c5d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual From e12fa4943609ff0b379878a819292606481e90be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:00 +0900 Subject: [PATCH 267/291] Integrate timeline into Compose --- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 2fe40dd010..2349c261cf 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Screens.Edit.Screens.Compose { @@ -13,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public Compose() { + ScrollableTimeline timeline; Children = new[] { new Container @@ -31,11 +33,22 @@ namespace osu.Game.Screens.Edit.Screens.Compose { Name = "Content", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 17, Vertical = 10 } + Padding = new MarginPadding { Horizontal = 17, Vertical = 10 }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 115 }, + Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + } + } } } } }; + + timeline.Beatmap.BindTo(Beatmap); } } } From 2844764e3c86a0b0acac92c133d97fedaf50aaa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:45 +0900 Subject: [PATCH 268/291] Hit Objects/Hit Sounds -> Hitobjects/Hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c662341f20..4c50dd4564 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -58,8 +58,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hit Objects" }, - new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Hitobjects" }, + new OsuCheckbox { LabelText = "Hitsounds" }, new OsuCheckbox { LabelText = "Waveform" } } } From de8f9325a3ed68cfc2888607a037318a37789a21 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 16:10:14 +0900 Subject: [PATCH 269/291] Implement TimelineButton and use for the magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 24 ++++------- .../Compose/Timeline/TimelineButton.cs | 42 +++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 2 +- osu.Game/osu.Game.csproj | 1 + 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 4c50dd4564..c1959f367b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -76,27 +76,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new FillFlowContainer + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 30), + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new SpriteIcon + new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_plus, - Colour = OsuColour.FromHex("555") - }, - new SpriteIcon - { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_minus, - Colour = OsuColour.FromHex("555") + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Icon = FontAwesome.fa_search_minus }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs new file mode 100644 index 0000000000..fc657325a4 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class TimelineButton : CompositeDrawable + { + public Action Action; + public readonly BindableBool Enabled = new BindableBool(true); + + public FontAwesome Icon + { + get { return button.Icon; } + set { button.Icon = value; } + } + + private readonly IconButton button; + + public TimelineButton() + { + InternalChild = button = new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + IconColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.FromHex("3A3A3A"), + FlashColour = OsuColour.FromHex("555"), + Action = () => Action?.Invoke() + }; + + button.Enabled.BindTo(Enabled); + Size = button.ButtonSize; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 00547145cd..02c32dfa56 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b0f8d8fac2..c054bf7b4e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,6 +275,7 @@ + From 78f2037d84391e75325ad418911f59ef2a185fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 09:42:06 +0200 Subject: [PATCH 270/291] Remove now obsolete RatioAdjust --- osu.Game/Graphics/Processing/RatioAdjust.cs | 27 --------------------- osu.Game/OsuGameBase.cs | 3 +-- osu.Game/osu.Game.csproj | 1 - 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 osu.Game/Graphics/Processing/RatioAdjust.cs diff --git a/osu.Game/Graphics/Processing/RatioAdjust.cs b/osu.Game/Graphics/Processing/RatioAdjust.cs deleted file mode 100644 index 640814d8e1..0000000000 --- a/osu.Game/Graphics/Processing/RatioAdjust.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Graphics.Containers; -using OpenTK; -using osu.Framework.Graphics; - -namespace osu.Game.Graphics.Processing -{ - internal class RatioAdjust : Container - { - public RatioAdjust() - { - RelativeSizeAxes = Axes.Both; - } - - protected override void Update() - { - base.Update(); - Vector2 parent = Parent.DrawSize; - - Scale = new Vector2(Math.Min(parent.Y / 768f, parent.X / 1024f)); - Size = new Vector2(1 / Scale.X); - } - } -} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e7bfa8a76..93eb1d76df 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; -using osu.Game.Graphics.Processing; using osu.Game.Online.API; using SQLite.Net; using osu.Framework.Graphics.Performance; @@ -186,7 +185,7 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - base.Content.Add(new RatioAdjust + base.Content.Add(new DrawSizePreservingFillContainer { Children = new Drawable[] { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 81f360f640..b7bb7de9e3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -312,7 +312,6 @@ - From 881eeaa650f9598e8055beddfa2afe928353654d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 16:57:05 +0900 Subject: [PATCH 271/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 07e84f60b0..31754e8fd0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 07e84f60b0d2ee443f366cb2e34bf25b680983dd +Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 From 4586877239ef234a7c3c1062c201fa9fde7521ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:31:21 +0900 Subject: [PATCH 272/291] Implement magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 9 ++++-- .../Timeline/ScrollingTimelineContainer.cs | 30 +++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c1959f367b..14c4f2d369 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -85,12 +85,17 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton + { + Icon = FontAwesome.fa_search_plus, + Action = () => timelineContainer.Zoom++ + }, new TimelineButton { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Icon = FontAwesome.fa_search_minus + Icon = FontAwesome.fa_search_minus, + Action = () => timelineContainer.Zoom-- }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a64f139e5a..209f0c9300 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -90,23 +90,43 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return; zoom = value; + // Make the zoom target default to the center of the graph if it hasn't been set + if (relativeContentZoomTarget == null) + relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X; + if (localZoomTarget == null) + localZoomTarget = DrawSize.X / 2; + Content.ResizeWidthTo(Zoom); + + // Update the scroll position to focus on the zoom target + float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value; + ScrollTo(scrollPos, false); + + relativeContentZoomTarget = null; + localZoomTarget = null; } } + /// + /// Zoom target as a relative position in the space. + /// + private float? relativeContentZoomTarget; + + /// + /// Zoom target as a position in our local space. + /// + private float? localZoomTarget; + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; Zoom += state.Mouse.WheelDelta; - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - return true; } } From 3c35a7a6ae5640fda75ce62f77f320e7ce59d676 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:37:40 +0900 Subject: [PATCH 273/291] graph -> waveform --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 209f0c9300..00b7e52e27 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -16,14 +16,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public readonly Bindable Beatmap = new Bindable(); - private readonly BeatmapWaveformGraph graph; + private readonly BeatmapWaveformGraph waveform; public ScrollingTimelineContainer() : base(Direction.Horizontal) { Masking = true; - Add(graph = new BeatmapWaveformGraph + Add(waveform = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.AutoSizeAxes = Axes.None; Content.RelativeSizeAxes = Axes.Both; - graph.Beatmap.BindTo(Beatmap); + waveform.Beatmap.BindTo(Beatmap); } private float minZoom = 1; From db672becbc19558b70645de20c9f59947ead1fa2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:50:51 +0900 Subject: [PATCH 274/291] Implement waveform checkbox --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 6 +++++- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 14c4f2d369..bf1237f1f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { new Box @@ -60,7 +61,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { new OsuCheckbox { LabelText = "Hitobjects" }, new OsuCheckbox { LabelText = "Hitsounds" }, - new OsuCheckbox { LabelText = "Waveform" } + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } } @@ -106,7 +107,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + waveformCheckbox.Current.Value = true; + timelineContainer.Beatmap.BindTo(Beatmap); + timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } protected override void Update() diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 00b7e52e27..a15db3d0df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); private readonly BeatmapWaveformGraph waveform; @@ -34,6 +35,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.RelativeSizeAxes = Axes.Both; waveform.Beatmap.BindTo(Beatmap); + WaveformVisible.ValueChanged += waveformVisibilityChanged; } private float minZoom = 1; @@ -129,5 +131,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } + + private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From 5ccfc1918e1a89a1639e016759e9c7b72ad29b4c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:51:01 +0900 Subject: [PATCH 275/291] Hook up more bindables for hitobjects/hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index bf1237f1f7..c64b223fa1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox hitObjectsCheckbox; + OsuCheckbox hitSoundsCheckbox; OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { @@ -59,8 +61,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hitobjects" }, - new OsuCheckbox { LabelText = "Hitsounds" }, + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } @@ -107,6 +109,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + hitObjectsCheckbox.Current.Value = true; + hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; timelineContainer.Beatmap.BindTo(Beatmap); diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a15db3d0df..c1bf2c3f57 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable HitObjectsVisible = new Bindable(); + public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); From a5817e6e75f803b50886b28d348fb33d53363088 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:23 +0900 Subject: [PATCH 276/291] Add a way to change the IconButton icon colour --- osu.Game/Graphics/UserInterface/IconButton.cs | 21 +++++++++++++++++-- osu.Game/Tests/Visual/TestCaseIconButton.cs | 12 +++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index d58f5797a3..afffd930ef 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -27,13 +27,28 @@ namespace osu.Game.Graphics.UserInterface set { flashColour = value; } } + private Color4? iconColour; /// /// The icon colour. This does not affect . /// public Color4 IconColour { - get { return icon.Colour; } - set { icon.Colour = value; } + get { return iconColour ?? Color4.White; } + set + { + iconColour = value; + icon.Colour = value; + } + } + + private Color4? iconHoverColour; + /// + /// The icon colour while the is hovered. + /// + public Color4 IconHoverColour + { + get { return iconHoverColour ?? IconColour; } + set { iconHoverColour = value; } } private Color4? hoverColour; @@ -133,12 +148,14 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(InputState state) { hover.FadeIn(500, Easing.OutQuint); + icon.FadeColour(IconHoverColour, 500, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { hover.FadeOut(500, Easing.OutQuint); + icon.FadeColour(IconColour, 500, Easing.OutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs index bec8f8314b..acde9df4a9 100644 --- a/osu.Game/Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -25,14 +25,18 @@ namespace osu.Game.Tests.Visual Children = new[] { new NamedIconButton("No change", new IconButton()), - new NamedIconButton("Green colours", new IconButton + new NamedIconButton("Background colours", new IconButton { - IconColour = Color4.LightGreen, FlashColour = Color4.DarkGreen, - HoverColour = Color4.Green + HoverColour = Color4.Green, }), new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), - new NamedIconButton("Unchanging size", new IconButton(), false) + new NamedIconButton("Unchanging size", new IconButton(), false), + new NamedIconButton("Icon colours", new IconButton + { + IconColour = Color4.Green, + IconHoverColour = Color4.Red + }) } }; } From a6901c0a2714e134608afbe9453a43abf1cec5f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:36 +0900 Subject: [PATCH 277/291] Change TimelineButton icon colour to white when hovered --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index fc657325a4..6fad1e5bb5 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,6 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Anchor = Anchor.Centre, Origin = Anchor.Centre, IconColour = OsuColour.FromHex("555"), + IconHoverColour = Color4.White, HoverColour = OsuColour.FromHex("3A3A3A"), FlashColour = OsuColour.FromHex("555"), Action = () => Action?.Invoke() From 1b031ca3280d104dadf9543ebf389e2719185b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:28:26 +0900 Subject: [PATCH 278/291] Fix potential read from empty queue in SPM counter --- .../Objects/Drawables/Pieces/SpinnerSpmCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index c079d3343b..ebe978f659 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces if (records.Count > 0) { var record = records.Peek(); - while (Time.Current - records.Peek().Time > spm_count_duration) + while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration) record = records.Dequeue(); SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } From ab623903367b74d2e30032fe5b04d61c6477774b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:32:39 +0900 Subject: [PATCH 279/291] Make TimelineButtons combined take up the full height of the timeline --- .../Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Edit/Screens/Compose/Timeline/TimelineButton.cs | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c64b223fa1..846a0d09f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -79,17 +79,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new Container + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, - Padding = new MarginPadding { Vertical = 5 }, + Masking = true, Children = new[] { new TimelineButton { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_plus, Action = () => timelineContainer.Zoom++ }, @@ -97,6 +99,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_minus, Action = () => timelineContainer.Zoom-- }, diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 6fad1e5bb5..8eec53c85f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -38,7 +39,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; button.Enabled.BindTo(Enabled); - Size = button.ButtonSize; + Width = button.ButtonSize.X; + } + + protected override void Update() + { + base.Update(); + + button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight); } } } From d9bf465b9c5a99b6c98dd323825461f3ef1c1c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 11:49:10 +0200 Subject: [PATCH 280/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..f1cda4873e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit f1cda4873eabc778afa323483e762491ee47f297 From 4d78a0492c78609bbee85ac78d410b55c8678951 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 19:15:59 +0900 Subject: [PATCH 281/291] Make creatorUsername a property so it is correctly deserialised --- osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index 470e13ea7b..d216b093ee 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -51,7 +51,7 @@ namespace osu.Game.Online.API.Requests private int onlineId { get; set; } [JsonProperty(@"creator")] - private string creatorUsername; + private string creatorUsername { get; set; } [JsonProperty(@"user_id")] private long creatorId = 1; From 8a5e25ce4b6401b86782415351879c64269f9d71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:50:12 +0900 Subject: [PATCH 282/291] Simplify waveform construction --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..c5235f4ecf 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit c5235f4ecfe933c04cbb2ee17adc714b9194fe0a diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index ad837b0e5b..a998b3eec3 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -574,15 +574,7 @@ namespace osu.Game.Beatmaps catch { return new TrackVirtual(); } } - protected override Waveform GetWaveform() - { - try - { - var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); - return trackData == null ? new Waveform() : new Waveform(trackData); - } - catch { return new Waveform(); } - } + protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile))); } /// From 70c55b23f4edecb0351a1e36afde330205a525ec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 20:30:15 +0900 Subject: [PATCH 283/291] Remove references to CodeAnalysisRulesets Having these produce warnings under certain compile environments. --- osu-framework | 2 +- osu.Game/osu.Game.csproj | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/osu-framework b/osu-framework index f1cda4873e..b43aecdce9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f1cda4873eabc778afa323483e762491ee47f297 +Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b7bb7de9e3..f14b441960 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -57,7 +57,6 @@ false AnyCPU true - AllRules.ruleset false false false @@ -77,7 +76,6 @@ false AnyCPU true - AllRules.ruleset false false @@ -103,7 +101,6 @@ false 6 prompt - AllRules.ruleset --tests false From fb8d8ec5524861f2ad7d96edd936a6b497c24bff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 21:26:25 +0900 Subject: [PATCH 284/291] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b43aecdce9..255b94f5dd 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 +Subproject commit 255b94f5dde0188db1a5b37daf9649659e2b8366 From 37b88d834e2584cb8f6aaeca89124300057ccd4f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:10:37 +0900 Subject: [PATCH 285/291] Adjust padding slightly --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 846a0d09f7..81beb4a4de 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Y, Width = 160, - Padding = new MarginPadding { Horizontal = 25 }, + Padding = new MarginPadding { Horizontal = 15 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 4), Children = new[] From 37fc69b9f71161088f3238cebbc5d90ef1fed5e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:02 +0900 Subject: [PATCH 286/291] Set a default zoom level that isn't the whole track --- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index c1bf2c3f57..47a77090b2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -38,6 +38,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; + + Zoom = 10; } private float minZoom = 1; From c0d64bf409b1e7afb9868a8040459d7e1e30fa21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:29 +0900 Subject: [PATCH 287/291] Use Gray instead of FromHex for grays --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 8eec53c85f..0c6fc5d133 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -31,10 +31,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, - IconColour = OsuColour.FromHex("555"), + IconColour = OsuColour.Gray(0.35f), IconHoverColour = Color4.White, - HoverColour = OsuColour.FromHex("3A3A3A"), - FlashColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.Gray(0.25f), + FlashColour = OsuColour.Gray(0.5f), Action = () => Action?.Invoke() }; From bb6b656ec688b6139bb5923d743e842949129766 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:27:22 +0900 Subject: [PATCH 288/291] Fix code review issues --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 4 +--- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index cffb2981bf..4c28a9d021 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -12,14 +12,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : DrawableCatchHitObject { - private const float pulp_size = 20; - public DrawableFruit(Fruit h) : base(h) { Origin = Anchor.Centre; - Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); + Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index f49799970d..6462f6f6a8 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects public class JuiceStream : CatchBaseHit, IHasCurve { /// - /// Scoring distance with a speed-adjusted beat length of 1 second. + /// Positional distance that results in a duration of one second, before any speed adjustments. /// private const float base_scoring_distance = 100; diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index f920f97790..363c330d3d 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,8 +15,6 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; - public double Scale = 1; - public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; @@ -202,4 +200,4 @@ namespace osu.Game.Rulesets.Objects return interpolateVertices(indexOfDistance(d), d) + Offset; } } -} \ No newline at end of file +} From abf54180800e6e207ba8af5da5cea91dbff1a0f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 14:06:34 +0900 Subject: [PATCH 289/291] Apply some renames and refactoring of loading logic Reduced publicly facing properties where possible. Also fixes a potentially bad state issue when the beatmapset was changed while a load was in progress. --- osu.Game/Overlays/BeatmapSet/PreviewButton.cs | 4 +- osu.Game/Overlays/Direct/PlayButton.cs | 79 +++++++++++-------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs index d040c89a91..f77a1f4a0a 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/PreviewButton.cs @@ -30,8 +30,8 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapSetInfo BeatmapSet { - get { return playButton.SetInfo; } - set { playButton.SetInfo = value; } + get { return playButton.BeatmapSet; } + set { playButton.BeatmapSet = value; } } public PreviewButton() diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 9ccce134d8..a98681234a 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -20,16 +20,17 @@ namespace osu.Game.Overlays.Direct public readonly Bindable Playing = new Bindable(); public Track Preview { get; private set; } - private BeatmapSetInfo setInfo; - public BeatmapSetInfo SetInfo + private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet { - get { return setInfo; } + get { return beatmapSet; } set { - if (value == setInfo) return; - setInfo = value; + if (value == beatmapSet) return; + beatmapSet = value; Playing.Value = false; + trackLoader = null; Preview = null; } } @@ -41,13 +42,10 @@ namespace osu.Game.Overlays.Direct private const float transition_duration = 500; - private bool loading; - public bool Loading + private bool loading { - get { return loading; } set { - loading = value; if (value) { loadingAnimation.Show(); @@ -63,7 +61,7 @@ namespace osu.Game.Overlays.Direct public PlayButton(BeatmapSetInfo setInfo = null) { - SetInfo = setInfo; + BeatmapSet = setInfo; AddRange(new Drawable[] { audioWrapper = new Container(), @@ -78,10 +76,12 @@ namespace osu.Game.Overlays.Direct loadingAnimation = new LoadingAnimation(), }); - Playing.ValueChanged += newValue => icon.Icon = newValue ? FontAwesome.fa_pause : FontAwesome.fa_play; - Playing.ValueChanged += newValue => icon.FadeColour(newValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); - - Playing.ValueChanged += updatePreviewTrack; + Playing.ValueChanged += playing => + { + icon.Icon = playing ? FontAwesome.fa_pause : FontAwesome.fa_play; + icon.FadeColour(playing || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + updatePreviewTrack(playing); + }; } [BackgroundDependencyLoader] @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - if(!Playing.Value) + if (!Playing.Value) icon.FadeColour(Color4.White, 120, Easing.InOutQuint); base.OnHoverLost(state); } @@ -113,35 +113,25 @@ namespace osu.Game.Overlays.Direct { base.Update(); - if(Preview?.HasCompleted ?? false) + if (Preview?.HasCompleted ?? false) { Playing.Value = false; Preview = null; } } - private void updatePreviewTrack(bool newValue) + private void updatePreviewTrack(bool playing) { - if (newValue) + if (playing) { if (Preview == null) { - Loading = true; - audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper("https://b.ppy.sh/preview/" + SetInfo.OnlineBeatmapSetID + ".mp3") - { - OnLoadComplete = d => - { - Loading = false; - Preview = (d as AudioLoadWrapper)?.Preview; - Playing.TriggerChange(); - }, - }); - } - else - { - Preview.Seek(0); - Preview.Start(); + beginAudioLoad(); + return; } + + Preview.Seek(0); + Preview.Start(); } else { @@ -149,13 +139,32 @@ namespace osu.Game.Overlays.Direct } } - private class AudioLoadWrapper : Drawable + private TrackLoader trackLoader; + + private void beginAudioLoad() + { + if (trackLoader != null) return; + + Add(new AsyncLoadWrapper(trackLoader = new TrackLoader($"https://b.ppy.sh/preview/{BeatmapSet.OnlineBeatmapSetID}.mp3") + { + OnLoadComplete = d => + { + // we may have been replaced by another loader + if (trackLoader != d) return; + + Preview = (d as TrackLoader)?.Preview; + Playing.TriggerChange(); + }, + })); + } + + private class TrackLoader : Drawable { private readonly string preview; public Track Preview; - public AudioLoadWrapper(string preview) + public TrackLoader(string preview) { this.preview = preview; } From 5b16f5d3b53b64146839ec87d7fdfa2ce4ecec6f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 14:15:44 +0900 Subject: [PATCH 290/291] Remove unused field --- osu.Game/Overlays/Direct/PlayButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index a98681234a..32435a4873 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Direct private Color4 hoverColour; private readonly SpriteIcon icon; private readonly LoadingAnimation loadingAnimation; - private readonly Container audioWrapper; private const float transition_duration = 500; @@ -64,7 +63,6 @@ namespace osu.Game.Overlays.Direct BeatmapSet = setInfo; AddRange(new Drawable[] { - audioWrapper = new Container(), icon = new SpriteIcon { Anchor = Anchor.Centre, From 070aceef1e5a2876d4b5d53e91b38e3b125d62df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Oct 2017 17:03:31 +0900 Subject: [PATCH 291/291] Move font and text size to class ProfileLink class --- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 3814fdcc18..337d4fe253 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -125,8 +125,6 @@ namespace osu.Game.Overlays.Profile Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Y = -48, - TextSize = 30, - Font = @"Exo2.0-RegularItalic", }, countryFlag = new DrawableFlag(user.Country?.FlagName) { @@ -547,6 +545,8 @@ namespace osu.Game.Overlays.Profile { Text = user.Username; Url = $@"https://osu.ppy.sh/users/{user.Id}"; + Font = @"Exo2.0-RegularItalic"; + TextSize = 30; } } }