From 76a95495d36e8069159775cc82a008317c47abc0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 17:30:10 +0900 Subject: [PATCH 01/12] Move shared code to base class --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 11 ----------- osu.Game/Overlays/Direct/DirectListPanel.cs | 15 --------------- osu.Game/Overlays/Direct/DirectPanel.cs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 98ab5e88f8..822edd02df 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -26,22 +26,11 @@ namespace osu.Game.Overlays.Direct { Height = 140 + vertical_padding; //full height of all the elements plus vertical padding (autosize uses the image) CornerRadius = 4; - Masking = true; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; } protected override void LoadComplete() { base.LoadComplete(); - - this.FadeInFromZero(200, Easing.Out); bottomPanel.LayoutDuration = 200; bottomPanel.LayoutEasing = Easing.Out; bottomPanel.Origin = Anchor.BottomLeft; diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 5b45fc7725..0821fbea3a 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -29,21 +29,6 @@ namespace osu.Game.Overlays.Direct RelativeSizeAxes = Axes.X; Height = height; CornerRadius = 5; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - this.FadeInFromZero(200, Easing.Out); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 2f048b0e3d..9395e6817d 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Extensions.Color4Extensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -10,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK.Graphics; namespace osu.Game.Overlays.Direct { @@ -20,6 +22,21 @@ namespace osu.Game.Overlays.Direct protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; + + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 3f, + Colour = Color4.Black.Opacity(0.25f), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(200, Easing.Out); } protected List GetDifficultyIcons() From 4e1cf329c88628cfaa537dd81c420c3350534e6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 17:39:39 +0900 Subject: [PATCH 02/12] Move background logic to base class; reduce overdraw after set fades in --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 10 ++------- osu.Game/Overlays/Direct/DirectPanel.cs | 25 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 822edd02df..5b648633c1 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -39,14 +39,8 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { - Children = new[] + AddRange(new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -174,7 +168,7 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, - }; + }); } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 9395e6817d..a56c15b532 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,10 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -19,6 +21,8 @@ namespace osu.Game.Overlays.Direct { protected readonly BeatmapSetInfo SetInfo; + protected Box BlackBackground; + protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; @@ -33,6 +37,21 @@ namespace osu.Game.Overlays.Direct }; } + [BackgroundDependencyLoader] + private void load() + { + AddRange(new[] + { + // temporary blackness until the actual background loads. + BlackBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + CreateBackground(), + }); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -55,7 +74,11 @@ namespace osu.Game.Overlays.Direct Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + OnLoadComplete = d => + { + d.FadeInFromZero(400, Easing.Out); + BlackBackground.Delay(400).FadeOut(); + }, }) { RelativeSizeAxes = Axes.Both, From a2549157ca578f548a4342e7f6d7a3ba0ffcbf90 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:18:03 +0900 Subject: [PATCH 03/12] Add hover effects --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 13 +--- osu.Game/Overlays/Direct/DirectPanel.cs | 85 +++++++++++++++++---- 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 5b648633c1..0cc1c18d8d 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays.Direct public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { Height = 140 + vertical_padding; //full height of all the elements plus vertical padding (autosize uses the image) - CornerRadius = 4; } protected override void LoadComplete() @@ -39,6 +38,8 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { + Content.CornerRadius = 4; + AddRange(new Drawable[] { new Box diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 0821fbea3a..d284c50bc4 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -28,20 +28,15 @@ namespace osu.Game.Overlays.Direct { RelativeSizeAxes = Axes.X; Height = height; - CornerRadius = 5; } [BackgroundDependencyLoader] private void load(LocalisationEngine localisation) { - Children = new[] + Content.CornerRadius = 5; + + AddRange(new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -132,7 +127,7 @@ namespace osu.Game.Overlays.Direct }, }, }, - }; + }); } private class DownloadButton : OsuClickableContainer diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a56c15b532..7e95c1674b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -9,11 +9,14 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; +using osu.Framework.Input; +using osu.Framework.MathUtils; namespace osu.Game.Overlays.Direct { @@ -23,35 +26,62 @@ namespace osu.Game.Overlays.Direct protected Box BlackBackground; + private const double hover_transition_time = 400; + + private Container content; + + protected override Container Content => content; + protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; - - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; } [BackgroundDependencyLoader] private void load() { - AddRange(new[] + AddInternal(content = new Container { - // temporary blackness until the actual background loads. - BlackBackground = new Box + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 2f, + Colour = Color4.Black.Opacity(0.25f), }, - CreateBackground(), + Children = new[] + { + // temporary blackness until the actual background loads. + BlackBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + CreateBackground(), + } }); } + protected override bool OnHover(InputState state) + { + content.FadeEdgeEffectTo(1f, hover_transition_time, Easing.OutQuint); + content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 14, hover_transition_time, Easing.OutQuint)); + content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + content.FadeEdgeEffectTo(0.25f, hover_transition_time, Easing.OutQuint); + content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 2, hover_transition_time, Easing.OutQuint)); + content.MoveToY(0, hover_transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -127,5 +157,30 @@ namespace osu.Game.Overlays.Direct Value = value; } } + + private class TransformEdgeEffectRadius : Transform + { + /// + /// Current value of the transformed colour in linear colour space. + /// + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + public override string TargetMember => "EdgeEffect.Colour"; + + protected override void Apply(Container c, double time) + { + EdgeEffectParameters e = c.EdgeEffect; + e.Radius = valueAt(time); + c.EdgeEffect = e; + } + + protected override void ReadIntoStartValue(Container d) => StartValue = d.EdgeEffect.Radius; + } } } From 36629f52074162d881c245d2293f139e889b39da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:51:34 +0900 Subject: [PATCH 04/12] Make ProgressBar usable in more places than just MusicController --- .../Graphics/UserInterface/ProgressBar.cs | 67 +++++++++++++++++++ osu.Game/Overlays/MusicController.cs | 45 ------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/ProgressBar.cs diff --git a/osu.Game/Graphics/UserInterface/ProgressBar.cs b/osu.Game/Graphics/UserInterface/ProgressBar.cs new file mode 100644 index 0000000000..f22983a6e6 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/ProgressBar.cs @@ -0,0 +1,67 @@ +// 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.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using OpenTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + public class ProgressBar : SliderBar + { + public Action OnSeek; + + private readonly Box fill; + private readonly Box background; + + public Color4 FillColour + { + set { fill.Colour = value; } + } + + public Color4 BackgroundColour + { + set + { + background.Alpha = 1; + background.Colour = value; + } + } + + public double EndTime + { + set { CurrentNumber.MaxValue = value; } + } + + public double CurrentTime + { + set { CurrentNumber.Value = value; } + } + + public ProgressBar() + { + CurrentNumber.MinValue = 0; + CurrentNumber.MaxValue = 1; + RelativeSizeAxes = Axes.X; + + Children = new Drawable[] + { + background = new Box + { + Alpha = 0, + RelativeSizeAxes = Axes.Both + }, + fill = new Box { RelativeSizeAxes = Axes.Y } + }; + } + + protected override void UpdateValue(float value) + { + fill.Width = value * UsableWidth; + } + + protected override void OnUserChange() => OnSeek?.Invoke(Current); + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d970089942..f2c90f009a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -15,7 +15,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Localisation; using osu.Framework.Threading; @@ -434,49 +433,5 @@ namespace osu.Game.Overlays sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } } - - private class ProgressBar : SliderBar - { - public Action OnSeek; - - private readonly Box fill; - - public Color4 FillColour - { - set { fill.Colour = value; } - } - - public double EndTime - { - set { CurrentNumber.MaxValue = value; } - } - - public double CurrentTime - { - set { CurrentNumber.Value = value; } - } - - public ProgressBar() - { - CurrentNumber.MinValue = 0; - CurrentNumber.MaxValue = 1; - RelativeSizeAxes = Axes.X; - - Children = new Drawable[] - { - fill = new Box - { - RelativeSizeAxes = Axes.Y - } - }; - } - - protected override void UpdateValue(float value) - { - fill.Width = value * UsableWidth; - } - - protected override void OnUserChange() => OnSeek?.Invoke(Current); - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 32a8df6357..f361c141f1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,7 @@ + From cacf256aade865ecc9748219827b56a06510125e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:51:50 +0900 Subject: [PATCH 05/12] Add placeholder download method with progress bar --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 7 +++++ osu.Game/Overlays/Direct/DirectListPanel.cs | 1 + osu.Game/Overlays/Direct/DirectPanel.cs | 29 ++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 0cc1c18d8d..3a9e75bd38 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -12,6 +12,7 @@ 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 { @@ -171,5 +172,11 @@ namespace osu.Game.Overlays.Direct }, }); } + + protected override bool OnClick(InputState state) + { + StartDownload(); + return true; + } } } diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index d284c50bc4..b3502b0827 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -124,6 +124,7 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Size = new Vector2(height - vertical_padding * 2), + Action = StartDownload }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7e95c1674b..8738d8ea90 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -17,6 +17,8 @@ using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; namespace osu.Game.Overlays.Direct { @@ -30,6 +32,9 @@ namespace osu.Game.Overlays.Direct private Container content; + private APIAccess api; + private ProgressBar progressBar; + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -38,8 +43,10 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load() + private void load(APIAccess api, OsuColour colours) { + this.api = api; + AddInternal(content = new Container { RelativeSizeAxes = Axes.Both, @@ -60,6 +67,16 @@ namespace osu.Game.Overlays.Direct Colour = Color4.Black, }, CreateBackground(), + progressBar = new ProgressBar + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Height = 0, + Alpha = 0, + BackgroundColour = Color4.Black.Opacity(0.7f), + FillColour = colours.Blue, + Depth = -1, + }, } }); } @@ -82,6 +99,16 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } + protected void StartDownload() + { + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0.5f; + + api.Queue(new APIRequest()); + } + protected override void LoadComplete() { base.LoadComplete(); From 314108146a9ae75bcdb82b7413bd998794febc94 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:14:17 +0900 Subject: [PATCH 06/12] Add a download API request --- osu.Game/Online/API/APIRequest.cs | 43 +++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 23268a9ca9..307afb2d2b 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -11,11 +11,11 @@ namespace osu.Game.Online.API /// An API request with a well-defined response type. /// /// Type of the response (used for deserialisation). - public class APIRequest : APIRequest + public abstract class APIRequest : APIRequest { protected override WebRequest CreateWebRequest() => new JsonWebRequest(Uri); - public APIRequest() + protected APIRequest() { base.Success += onSuccess; } @@ -28,10 +28,36 @@ namespace osu.Game.Online.API public new event APISuccessHandler Success; } + public abstract class APIDownloadRequest : APIRequest + { + protected override WebRequest CreateWebRequest() + { + var request = new WebRequest(Uri); + request.DownloadProgress += request_Progress; + return request; + } + + private void request_Progress(WebRequest request, long current, long total) => API.Scheduler.Add(delegate { Progress?.Invoke(current, total); }); + + protected APIDownloadRequest() + { + base.Success += onSuccess; + } + + private void onSuccess() + { + Success?.Invoke(WebRequest.ResponseData); + } + + public event APIProgressHandler Progress; + + public new event APISuccessHandler Success; + } + /// /// AN API request with no specified response type. /// - public class APIRequest + public abstract class APIRequest { /// /// The maximum amount of time before this request will fail. @@ -42,7 +68,7 @@ namespace osu.Game.Online.API protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri); - protected virtual string Uri => $@"{api.Endpoint}/api/v2/{Target}"; + protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}"; private double remainingTime => Math.Max(0, Timeout - (DateTime.Now.TotalMilliseconds() - (startTime ?? 0))); @@ -52,7 +78,7 @@ namespace osu.Game.Online.API public double StartTime => startTime ?? -1; - private APIAccess api; + protected APIAccess API; protected WebRequest WebRequest; public event APISuccessHandler Success; @@ -64,7 +90,7 @@ namespace osu.Game.Online.API public void Perform(APIAccess api) { - this.api = api; + API = api; if (checkAndProcessFailure()) return; @@ -109,9 +135,9 @@ namespace osu.Game.Online.API /// Whether we are in a failed or cancelled state. private bool checkAndProcessFailure() { - if (api == null || pendingFailure == null) return cancelled; + if (API == null || pendingFailure == null) return cancelled; - api.Scheduler.Add(pendingFailure); + API.Scheduler.Add(pendingFailure); pendingFailure = null; return true; } @@ -119,5 +145,6 @@ namespace osu.Game.Online.API public delegate void APIFailureHandler(Exception e); public delegate void APISuccessHandler(); + public delegate void APIProgressHandler(long current, long total); public delegate void APISuccessHandler(T content); } From 3c10b2d3d9b44e06bf95f88a8c26371d976634b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:14:35 +0900 Subject: [PATCH 07/12] Populate set IDs in GetBeatmapSetsResponse --- osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index ca984d3511..e4763f73ee 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -46,6 +46,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty(@"favourite_count")] private int favouriteCount { get; set; } + [JsonProperty(@"id")] + private int onlineId { get; set; } + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } @@ -53,6 +56,7 @@ namespace osu.Game.Online.API.Requests { return new BeatmapSetInfo { + OnlineBeatmapSetID = onlineId, Metadata = this, OnlineInfo = new BeatmapSetOnlineInfo { From 9c82593c9e82a23ebc9f435674f1b6172a1351e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:15:45 +0900 Subject: [PATCH 08/12] Add cancel event to ProgressNotification --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index f42b4b6cb3..a31291e1b8 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -152,11 +152,14 @@ namespace osu.Game.Overlays.Notifications break; case ProgressNotificationState.Active: case ProgressNotificationState.Queued: - State = ProgressNotificationState.Cancelled; + if (CancelRequested?.Invoke() != false) + State = ProgressNotificationState.Cancelled; break; } } + public Func CancelRequested { get; set; } + /// /// The function to post completion notifications back to. /// From 32a23c7fe41fd2c4f978385fdb6f32f576d9e0dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:16:03 +0900 Subject: [PATCH 09/12] Add initial osu!direct beatmap download and import process --- osu.Game/Overlays/Direct/DirectPanel.cs | 82 ++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 8738d8ea90..b44a100d3c 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; +using System.IO; +using System.Threading.Tasks; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -19,6 +21,9 @@ using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; +using osu.Framework.Logging; +using osu.Game.Beatmaps.IO; +using osu.Game.Overlays.Notifications; namespace osu.Game.Overlays.Direct { @@ -34,6 +39,8 @@ namespace osu.Game.Overlays.Direct private APIAccess api; private ProgressBar progressBar; + private BeatmapManager beatmaps; + private NotificationOverlay notifications; protected override Container Content => content; @@ -43,9 +50,11 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load(APIAccess api, OsuColour colours) + private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) { this.api = api; + this.beatmaps = beatmaps; + this.notifications = notifications; AddInternal(content = new Container { @@ -101,12 +110,79 @@ namespace osu.Game.Overlays.Direct protected void StartDownload() { + if (!api.LocalUser.Value.IsSupporter) + { + notifications.Post(new SimpleNotification + { + Icon = FontAwesome.fa_superpowers, + Text = "You gotta be a supporter to download for now 'yo" + }); + return; + } + progressBar.FadeIn(400, Easing.OutQuint); progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - progressBar.Current.Value = 0.5f; + progressBar.Current.Value = 0; - api.Queue(new APIRequest()); + ProgressNotification downloadNotification = new ProgressNotification + { + Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}", + }; + + var request = new DownloadBeatmapSetRequest(SetInfo); + request.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + downloadNotification.State = ProgressNotificationState.Completed; + Logger.Error(e, "Failed to get beatmap download information"); + }; + + request.Progress += (current, total) => + { + float progress = (float)current / total; + + progressBar.Current.Value = progress; + + downloadNotification.State = ProgressNotificationState.Active; + downloadNotification.Progress = progress; + }; + + request.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + + downloadNotification.State = ProgressNotificationState.Completed; + + using (var stream = new MemoryStream(data)) + using (var archive = new OszArchiveReader(stream)) + beatmaps.Import(archive); + }; + + downloadNotification.CancelRequested += () => + { + request.Cancel(); + return true; + }; + + notifications.Post(downloadNotification); + + // don't run in the main api queue as this is a long-running task. + Task.Run(() => request.Perform(api)); + } + + public class DownloadBeatmapSetRequest : APIDownloadRequest + { + private readonly BeatmapSetInfo beatmapSet; + + public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + { + this.beatmapSet = beatmapSet; + } + + protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; } protected override void LoadComplete() From 9adff5f697221b0d7f8ab9460315c681345a6a3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:18:47 +0900 Subject: [PATCH 10/12] Add osu!direct toggle to toolbar --- osu.Game/OsuGame.cs | 1 + osu.Game/Overlays/Toolbar/Toolbar.cs | 1 + .../Overlays/Toolbar/ToolbarDirectButton.cs | 19 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 22 insertions(+) create mode 100644 osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 8c82071c23..43e3731166 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -219,6 +219,7 @@ namespace osu.Game dependencies.Cache(settings); dependencies.Cache(social); + dependencies.Cache(direct); dependencies.Cache(chat); dependencies.Cache(userProfile); dependencies.Cache(musicController); diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 32344ca7eb..e36db1f9da 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -58,6 +58,7 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { + new ToolbarDirectButton(), new ToolbarChatButton(), new ToolbarSocialButton(), new ToolbarMusicButton(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs new file mode 100644 index 0000000000..484b079d23 --- /dev/null +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs @@ -0,0 +1,19 @@ +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Toolbar +{ + internal class ToolbarDirectButton : ToolbarOverlayToggleButton + { + public ToolbarDirectButton() + { + SetIcon(FontAwesome.fa_download); + } + + [BackgroundDependencyLoader] + private void load(DirectOverlay direct) + { + StateContainer = direct; + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f361c141f1..15c400b21e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -130,6 +130,7 @@ + From 0082640548d3e6cab5cdfbfe0ed2cb442511ccda Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:25:18 +0900 Subject: [PATCH 11/12] Add missing licence header --- osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs index 484b079d23..32e149b31a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.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.Graphics; From febf0348be646d1af5aeda1ae1ee8dcf5206a298 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 21:26:50 +0900 Subject: [PATCH 12/12] Permit nulls to allow test cases to run successfully --- osu.Game/Overlays/Direct/DirectPanel.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index b44a100d3c..bc30fb83f5 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Direct SetInfo = setInfo; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(permitNulls: true)] private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) { this.api = api; @@ -110,6 +110,8 @@ namespace osu.Game.Overlays.Direct protected void StartDownload() { + if (api == null) return; + if (!api.LocalUser.Value.IsSupporter) { notifications.Post(new SimpleNotification