diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs deleted file mode 100644 index baeeaf81a4..0000000000 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2007-2018 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.Configuration; -using osu.Framework.Graphics; -using osu.Game.Online.API.Requests; - -namespace osu.Game.Beatmaps.Drawables -{ - /// - /// A component to allow downloading of a beatmap set. Automatically handles state syncing between other instances. - /// - public class BeatmapSetDownloader : Component - { - private readonly BeatmapSetInfo set; - private readonly bool noVideo; - - private BeatmapManager beatmaps; - - /// - /// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded. - /// - public readonly Bindable DownloadState = new Bindable(); - - public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false) - { - this.set = set; - this.noVideo = noVideo; - } - - [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps) - { - this.beatmaps = beatmaps; - - beatmaps.ItemAdded += setAdded; - beatmaps.ItemRemoved += setRemoved; - beatmaps.BeatmapDownloadBegan += downloadBegan; - beatmaps.BeatmapDownloadFailed += downloadFailed; - - // initial value - if (set.OnlineBeatmapSetID != null && beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any()) - DownloadState.Value = DownloadStatus.Downloaded; - else if (beatmaps.GetExistingDownload(set) != null) - DownloadState.Value = DownloadStatus.Downloading; - else - DownloadState.Value = DownloadStatus.NotDownloaded; - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (beatmaps != null) - { - beatmaps.ItemAdded -= setAdded; - beatmaps.ItemRemoved -= setRemoved; - beatmaps.BeatmapDownloadBegan -= downloadBegan; - beatmaps.BeatmapDownloadFailed -= downloadFailed; - } - } - - /// - /// Begin downloading the associated beatmap set. - /// - /// True if downloading began. False if an existing download is active or completed. - public void Download() - { - if (DownloadState.Value > DownloadStatus.NotDownloaded) - return; - - if (beatmaps.Download(set, noVideo)) - { - // Only change state if download can happen - DownloadState.Value = DownloadStatus.Downloading; - } - } - - private void setAdded(BeatmapSetInfo s, bool existing, bool silent) => Schedule(() => - { - if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - DownloadState.Value = DownloadStatus.Downloaded; - }); - - private void setRemoved(BeatmapSetInfo s) => Schedule(() => - { - if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - DownloadState.Value = DownloadStatus.NotDownloaded; - }); - - private void downloadBegan(DownloadBeatmapSetRequest d) - { - if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - DownloadState.Value = DownloadStatus.Downloading; - } - - private void downloadFailed(DownloadBeatmapSetRequest d) - { - if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - DownloadState.Value = DownloadStatus.NotDownloaded; - } - - public enum DownloadStatus - { - NotDownloaded, - Downloading, - Downloaded, - } - } -} diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index c72bf8cbed..b57a077f53 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.API.Requests { public readonly BeatmapSetInfo BeatmapSet; - public Action DownloadProgressed; + public event Action DownloadProgressed; private readonly bool noVideo; diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index a44e2c7fab..deaa648844 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -7,8 +7,8 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Overlays.Direct; @@ -18,75 +18,100 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class DownloadButton : HeaderButton, IHasTooltip + public class DownloadButton : DownloadTrackingComposite, IHasTooltip { - public string TooltipText => Enabled ? null : "You gotta be an osu!supporter to download for now 'yo"; + private readonly bool noVideo; + public string TooltipText => button.Enabled ? null : "You gotta be an osu!supporter to download for now 'yo"; private readonly IBindable localUser = new Bindable(); - public DownloadButton(BeatmapSetInfo set, bool noVideo = false) - { - Width = 120; + private ShakeContainer shakeContainer; + private HeaderButton button; - BeatmapSetDownloader downloader; + public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) + : base(beatmapSet) + { + this.noVideo = noVideo; + + Width = 120; + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(APIAccess api, BeatmapManager beatmaps) + { FillFlowContainer textSprites; - AddRange(new Drawable[] + AddRangeInternal(new Drawable[] { - new Container + shakeContainer = new ShakeContainer { Depth = -1, RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 10 }, + Masking = true, + CornerRadius = 5, Children = new Drawable[] { - downloader = new BeatmapSetDownloader(set, noVideo), - textSprites = new FillFlowContainer + button = new HeaderButton { RelativeSizeAxes = Axes.Both }, + new Container { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - AutoSizeDuration = 500, - AutoSizeEasing = Easing.OutQuint, - Direction = FillDirection.Vertical, + // cannot nest inside here due to the structure of button (putting things in its own content). + // requires framework fix. + Padding = new MarginPadding { Horizontal = 10 }, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + textSprites = new FillFlowContainer + { + Depth = -1, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + AutoSizeDuration = 500, + AutoSizeEasing = Easing.OutQuint, + Direction = FillDirection.Vertical, + }, + new SpriteIcon + { + Depth = -1, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Icon = FontAwesome.fa_download, + Size = new Vector2(16), + Margin = new MarginPadding { Right = 5 }, + }, + } }, - new SpriteIcon + new DownloadProgressBar(BeatmapSet) { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Icon = FontAwesome.fa_download, - Size = new Vector2(16), - Margin = new MarginPadding { Right = 5 }, + Depth = -2, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, }, }, }, - new DownloadProgressBar(set) - { - Depth = -2, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - }, }); - Action = () => + button.Action = () => { - if (downloader.DownloadState.Value == BeatmapSetDownloader.DownloadStatus.Downloading) + if (State.Value == DownloadState.Downloading) { - Content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine); + shakeContainer.Shake(); return; } - downloader.Download(); + beatmaps.Download(BeatmapSet, noVideo); }; - downloader.DownloadState.ValueChanged += state => + localUser.BindTo(api.LocalUser); + localUser.BindValueChanged(userChanged, true); + button.Enabled.BindValueChanged(enabledChanged, true); + + State.BindValueChanged(state => { switch (state) { - case BeatmapSetDownloader.DownloadStatus.Downloading: + case DownloadState.Downloading: textSprites.Children = new Drawable[] { new OsuSpriteText @@ -97,10 +122,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, }; break; - case BeatmapSetDownloader.DownloadStatus.Downloaded: + case DownloadState.Downloaded: this.FadeOut(200); break; - case BeatmapSetDownloader.DownloadStatus.NotDownloaded: + case DownloadState.NotDownloaded: textSprites.Children = new Drawable[] { new OsuSpriteText @@ -111,7 +136,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, new OsuSpriteText { - Text = set.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty, + Text = BeatmapSet.Value.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty, TextSize = 11, Font = @"Exo2.0-Bold", }, @@ -119,20 +144,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons this.FadeIn(200); break; } - }; - - downloader.DownloadState.TriggerChange(); + }, true); } - [BackgroundDependencyLoader] - private void load(APIAccess api) - { - localUser.BindTo(api.LocalUser); - localUser.BindValueChanged(userChanged, true); - Enabled.BindValueChanged(enabledChanged, true); - } - - private void userChanged(User user) => Enabled.Value = user.IsSupporter; + private void userChanged(User user) => button.Enabled.Value = user.IsSupporter; private void enabledChanged(bool enabled) => this.FadeColour(enabled ? Color4.White : Color4.Gray, 200, Easing.OutQuint); } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index c702c7cb87..6a7fc1c0ce 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -13,12 +13,14 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.BeatmapSet.Buttons; +using osu.Game.Overlays.Direct; using osuTK; using osuTK.Graphics; +using DownloadButton = osu.Game.Overlays.BeatmapSet.Buttons.DownloadButton; namespace osu.Game.Overlays.BeatmapSet { - public class Header : Container + public class Header : DownloadTrackingComposite { private const float transition_duration = 200; private const float tabs_height = 50; @@ -35,78 +37,16 @@ namespace osu.Game.Overlays.BeatmapSet public readonly BeatmapPicker Picker; - private BeatmapSetInfo beatmapSet; private readonly FavouriteButton favouriteButton; - public BeatmapSetInfo BeatmapSet - { - get { return beatmapSet; } - set - { - if (value == beatmapSet) return; - beatmapSet = value; - - Picker.BeatmapSet = author.BeatmapSet = Details.BeatmapSet = BeatmapSet; - - updateDisplay(); - } - } - - private BeatmapSetDownloader downloader; - - private void updateDisplay() - { - downloader?.Expire(); - - - title.Text = BeatmapSet?.Metadata.Title ?? string.Empty; - artist.Text = BeatmapSet?.Metadata.Artist ?? string.Empty; - onlineStatusPill.Status = BeatmapSet?.OnlineInfo.Status ?? BeatmapSetOnlineStatus.None; - cover.BeatmapSet = BeatmapSet; - - if (BeatmapSet != null) - { - downloadButtonsContainer.FadeIn(transition_duration); - favouriteButton.FadeIn(transition_duration); - - Add(downloader = new BeatmapSetDownloader(BeatmapSet)); - downloader.DownloadState.BindValueChanged(state => - { - switch (state) - { - case BeatmapSetDownloader.DownloadStatus.Downloaded: - // temporary for UX until new design is implemented. - downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet) - { - Width = 50, - RelativeSizeAxes = Axes.Y - }; - break; - case BeatmapSetDownloader.DownloadStatus.Downloading: - // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet); - break; - default: - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet); - if (BeatmapSet.OnlineInfo.HasVideo) - downloadButtonsContainer.Add(new DownloadButton(BeatmapSet, true)); - break; - } - }, true); - } - else - { - downloadButtonsContainer.FadeOut(transition_duration); - favouriteButton.FadeOut(transition_duration); - } - } - public Header() { ExternalLinkButton externalLink; + RelativeSizeAxes = Axes.X; Height = 400; Masking = true; + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.25f), @@ -114,7 +54,8 @@ namespace osu.Game.Overlays.BeatmapSet Radius = 3, Offset = new Vector2(0f, 1f), }; - Children = new Drawable[] + + InternalChildren = new Drawable[] { new Container { @@ -241,14 +182,64 @@ namespace osu.Game.Overlays.BeatmapSet }; Picker.Beatmap.ValueChanged += b => Details.Beatmap = b; - Picker.Beatmap.ValueChanged += b => externalLink.Link = $@"https://osu.ppy.sh/beatmapsets/{BeatmapSet?.OnlineBeatmapSetID}#{b?.Ruleset.ShortName}/{b?.OnlineBeatmapID}"; + Picker.Beatmap.ValueChanged += b => externalLink.Link = $@"https://osu.ppy.sh/beatmapsets/{BeatmapSet.Value?.OnlineBeatmapSetID}#{b?.Ruleset.ShortName}/{b?.OnlineBeatmapID}"; } [BackgroundDependencyLoader] private void load(OsuColour colours) { tabsBg.Colour = colours.Gray3; - updateDisplay(); + + BeatmapSet.BindValueChanged(beatmapSet => + { + Picker.BeatmapSet = author.BeatmapSet = Details.BeatmapSet = beatmapSet; + + title.Text = beatmapSet?.Metadata.Title ?? string.Empty; + artist.Text = beatmapSet?.Metadata.Artist ?? string.Empty; + onlineStatusPill.Status = beatmapSet?.OnlineInfo.Status ?? BeatmapSetOnlineStatus.None; + cover.BeatmapSet = beatmapSet; + + if (beatmapSet != null) + { + downloadButtonsContainer.FadeIn(transition_duration); + favouriteButton.FadeIn(transition_duration); + } + else + { + downloadButtonsContainer.FadeOut(transition_duration); + favouriteButton.FadeOut(transition_duration); + } + + updateDownloadButtons(); + }); + + State.BindValueChanged(_ => updateDownloadButtons(), true); + } + + private void updateDownloadButtons() + { + if (BeatmapSet.Value == null) return; + switch (State.Value) + { + case DownloadState.LocallyAvailable: + // temporary for UX until new design is implemented. + downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet) + { + Width = 50, + RelativeSizeAxes = Axes.Y + }; + break; + case DownloadState.Downloading: + case DownloadState.Downloaded: + // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet); + break; + default: + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet); + if (BeatmapSet.Value.OnlineInfo.HasVideo) + downloadButtonsContainer.Add(new DownloadButton(BeatmapSet, true)); + break; + } } } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 6294851415..84d7861aa0 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays if (value == beatmapSet) return; - header.BeatmapSet = info.BeatmapSet = beatmapSet = value; + header.BeatmapSet.Value = info.BeatmapSet = beatmapSet = value; } } @@ -140,7 +140,7 @@ namespace osu.Game.Overlays req.Success += res => { BeatmapSet = res.ToBeatmapSet(rulesets); - header.Picker.Beatmap.Value = header.BeatmapSet.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId); + header.Picker.Beatmap.Value = header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId); }; api.Queue(req); Show(); diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index e326f5e592..32cc8b351a 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -5,103 +5,114 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osuTK; namespace osu.Game.Overlays.Direct { - public class DownloadButton : OsuAnimatedButton + public class DownloadButton : DownloadTrackingComposite { - private readonly BeatmapSetInfo beatmapSet; + private readonly bool noVideo; private readonly SpriteIcon icon; private readonly SpriteIcon checkmark; - private readonly BeatmapSetDownloader downloader; private readonly Box background; private OsuColour colours; - public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) - { - this.beatmapSet = beatmapSet; + private readonly ShakeContainer shakeContainer; - AddRange(new Drawable[] + private readonly OsuAnimatedButton button; + + public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) + : base(beatmapSet) + { + this.noVideo = noVideo; + + InternalChild = shakeContainer = new ShakeContainer { - downloader = new BeatmapSetDownloader(beatmapSet, noVideo), - background = new Box + RelativeSizeAxes = Axes.Both, + Child = button = new OsuAnimatedButton { RelativeSizeAxes = Axes.Both, - Depth = float.MaxValue - }, - icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(13), - Icon = FontAwesome.fa_download, - }, - checkmark = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - X = 8, - Size = Vector2.Zero, - Icon = FontAwesome.fa_check, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(13), + Icon = FontAwesome.fa_download, + }, + checkmark = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + X = 8, + Size = Vector2.Zero, + Icon = FontAwesome.fa_check, + } + } } - }); + }; } protected override void LoadComplete() { base.LoadComplete(); - downloader.DownloadState.BindValueChanged(updateState, true); + + State.BindValueChanged(updateState, true); FinishTransforms(true); } [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, OsuGame game) + private void load(OsuColour colours, OsuGame game, BeatmapManager beatmaps) { this.colours = colours; - Action = () => + button.Action = () => { - switch (downloader.DownloadState.Value) + switch (State.Value) { - case BeatmapSetDownloader.DownloadStatus.Downloading: - // todo: replace with ShakeContainer after https://github.com/ppy/osu/pull/2909 is merged. - Content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine); + case DownloadState.Downloading: + case DownloadState.Downloaded: + shakeContainer.Shake(); break; - case BeatmapSetDownloader.DownloadStatus.Downloaded: - game.PresentBeatmap(beatmapSet); + case DownloadState.LocallyAvailable: + game.PresentBeatmap(BeatmapSet); break; default: - downloader.Download(); + beatmaps.Download(BeatmapSet, noVideo); break; } }; } - private void updateState(BeatmapSetDownloader.DownloadStatus state) + private void updateState(DownloadState state) { switch (state) { - case BeatmapSetDownloader.DownloadStatus.NotDownloaded: + case DownloadState.NotDownloaded: background.FadeColour(colours.Gray4, 500, Easing.InOutExpo); icon.MoveToX(0, 500, Easing.InOutExpo); checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo); break; - case BeatmapSetDownloader.DownloadStatus.Downloading: + case DownloadState.Downloading: background.FadeColour(colours.Blue, 500, Easing.InOutExpo); icon.MoveToX(0, 500, Easing.InOutExpo); checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo); break; - - case BeatmapSetDownloader.DownloadStatus.Downloaded: + case DownloadState.Downloaded: + background.FadeColour(colours.Yellow, 500, Easing.InOutExpo); + break; + case DownloadState.LocallyAvailable: background.FadeColour(colours.Green, 500, Easing.InOutExpo); icon.MoveToX(-8, 500, Easing.InOutExpo); checkmark.ScaleTo(new Vector2(13), 500, Easing.InOutExpo); diff --git a/osu.Game/Overlays/Direct/DownloadProgressBar.cs b/osu.Game/Overlays/Direct/DownloadProgressBar.cs index 60632980a7..b416377d0f 100644 --- a/osu.Game/Overlays/Direct/DownloadProgressBar.cs +++ b/osu.Game/Overlays/Direct/DownloadProgressBar.cs @@ -11,14 +11,12 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Direct { - public class DownloadProgressBar : DownloadTrackingComponent + public class DownloadProgressBar : DownloadTrackingComposite { private readonly ProgressBar progressBar; - private OsuColour colours; - - public DownloadProgressBar(BeatmapSetInfo setInfo) - : base(setInfo) + public DownloadProgressBar(BeatmapSetInfo beatmapSet) + : base(beatmapSet) { AddInternal(progressBar = new ProgressBar { @@ -33,38 +31,31 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader(true)] private void load(OsuColour colours) { - this.colours = colours; - progressBar.FillColour = colours.Blue; progressBar.BackgroundColour = Color4.Black.Opacity(0.7f); - } + progressBar.Current = Progress; - protected override void DownloadFailed() - { - progressBar.Current.Value = 0; - progressBar.FadeOut(500); - } - - protected override void DownloadComleted() - { - progressBar.Current.Value = 1; - progressBar.FillColour = colours.Yellow; - } - - protected override void DownloadStarted() - { - progressBar.FadeIn(400, Easing.OutQuint); - progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - } - - protected override void BeatmapImported() - { - progressBar.FadeOut(500); - } - - protected override void ProgressChanged(float progress) - { - progressBar.Current.Value = progress; + State.BindValueChanged(state => + { + switch (state) + { + case DownloadState.NotDownloaded: + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + break; + case DownloadState.Downloading: + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + break; + case DownloadState.Downloaded: + progressBar.Current.Value = 1; + progressBar.FillColour = colours.Yellow; + break; + case DownloadState.LocallyAvailable: + progressBar.FadeOut(500); + break; + } + }, true); } } } diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComponent.cs b/osu.Game/Overlays/Direct/DownloadTrackingComponent.cs index 8b42832554..0bfb28978f 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComponent.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComponent.cs @@ -1,21 +1,56 @@ -// Copyright (c) 2007-2019 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Direct { - public abstract class DownloadTrackingComponent : CompositeDrawable + public abstract class DownloadTrackingComposite : CompositeDrawable { - private readonly BeatmapSetInfo setInfo; + public readonly Bindable BeatmapSet = new Bindable(); + private BeatmapManager beatmaps; - protected DownloadTrackingComponent(BeatmapSetInfo beatmapSetInfo) + /// + /// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded. + /// + protected readonly Bindable State = new Bindable(); + + protected readonly Bindable Progress = new Bindable(); + + protected DownloadTrackingComposite(BeatmapSetInfo beatmapSet = null) { - setInfo = beatmapSetInfo; + BeatmapSet.Value = beatmapSet; + } + + [BackgroundDependencyLoader(true)] + private void load(BeatmapManager beatmaps) + { + this.beatmaps = beatmaps; + + BeatmapSet.BindValueChanged(set => + { + if (set == null) + attachDownload(null); + else if (beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID).Any()) + State.Value = DownloadState.LocallyAvailable; + else + attachDownload(beatmaps.GetExistingDownload(set)); + }, true); + + beatmaps.BeatmapDownloadBegan += download => + { + if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) + attachDownload(download); + }; + + beatmaps.ItemAdded += setAdded; } #region Disposal @@ -29,49 +64,62 @@ namespace osu.Game.Overlays.Direct #endregion - [BackgroundDependencyLoader(true)] - private void load(BeatmapManager beatmaps) - { - this.beatmaps = beatmaps; - - var downloadRequest = beatmaps.GetExistingDownload(setInfo); - - if (downloadRequest != null) - attachDownload(downloadRequest); - - beatmaps.BeatmapDownloadBegan += attachDownload; - beatmaps.ItemAdded += setAdded; - } + private DownloadBeatmapSetRequest attachedRequest; private void attachDownload(DownloadBeatmapSetRequest request) { - if (request.BeatmapSet.OnlineBeatmapSetID != setInfo.OnlineBeatmapSetID) - return; + if (attachedRequest != null) + { + attachedRequest.Failure -= onRequestFailure; + attachedRequest.DownloadProgressed -= onRequestProgress; + attachedRequest.Success -= onRequestSuccess; + } - DownloadStarted(); + attachedRequest = request; - request.Failure += e => { DownloadFailed(); }; - - request.DownloadProgressed += progress => Schedule(() => ProgressChanged(progress)); - request.Success += data => { DownloadComleted(); }; + if (attachedRequest != null) + { + State.Value = DownloadState.Downloading; + attachedRequest.Failure += onRequestFailure; + attachedRequest.DownloadProgressed += onRequestProgress; + attachedRequest.Success += onRequestSuccess; + } + else + { + State.Value = DownloadState.NotDownloaded; + } } - protected abstract void ProgressChanged(float progress); + private void onRequestSuccess(byte[] data) + { + Schedule(() => State.Value = DownloadState.Downloaded); + attachDownload(null); + } - protected abstract void DownloadFailed(); + private void onRequestProgress(float progress) + { + Schedule(() => Progress.Value = progress); + } - protected abstract void DownloadComleted(); - - protected abstract void BeatmapImported(); - - protected abstract void DownloadStarted(); + private void onRequestFailure(Exception e) + { + Schedule(() => State.Value = DownloadState.Downloading); + } private void setAdded(BeatmapSetInfo s, bool existing, bool silent) { - if (s.OnlineBeatmapSetID != setInfo.OnlineBeatmapSetID) + if (s.OnlineBeatmapSetID != BeatmapSet.Value?.OnlineBeatmapSetID) return; - Schedule(BeatmapImported); + Schedule(() => State.Value = DownloadState.LocallyAvailable); } } -} \ No newline at end of file + + public enum DownloadState + { + NotDownloaded, + Downloading, + Downloaded, + LocallyAvailable + } +}