1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 23:12:56 +08:00

Add SpotlightsLayout to RankingsOverlay

This commit is contained in:
Andrei Zavatski 2020-02-11 02:35:23 +03:00
parent b04a4b5c8a
commit 0b6558dc40
6 changed files with 85 additions and 167 deletions

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Rankings;
using osu.Game.Rulesets;
@ -35,25 +34,7 @@ namespace osu.Game.Tests.Visual.Online
{
Current = { BindTarget = scope },
Country = { BindTarget = countryBindable },
Ruleset = { BindTarget = ruleset },
Spotlights = new[]
{
new APISpotlight
{
Id = 1,
Name = "Spotlight 1"
},
new APISpotlight
{
Id = 2,
Name = "Spotlight 2"
},
new APISpotlight
{
Id = 3,
Name = "Spotlight 3"
}
}
Ruleset = { BindTarget = ruleset }
});
var country = new Country

View File

@ -35,6 +35,12 @@ namespace osu.Game.Tests.Visual.Online
Add(selector = new SpotlightSelector());
}
[Test]
public void TestVisibility()
{
AddStep("Toggle Visibility", selector.ToggleVisibility);
}
[Test]
public void TestLocalSpotlights()
{

View File

@ -6,24 +6,14 @@ using osu.Framework.Bindables;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Users;
using System.Collections.Generic;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.Rankings
{
public class RankingsOverlayHeader : TabControlOverlayHeader<RankingsScope>
{
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
public readonly Bindable<APISpotlight> Spotlight = new Bindable<APISpotlight>();
public readonly Bindable<Country> Country = new Bindable<Country>();
public IEnumerable<APISpotlight> Spotlights
{
get => SpotlightSelector.Spotlights;
set => SpotlightSelector.Spotlights = value;
}
protected override ScreenTitle CreateTitle() => new RankingsTitle
{
Scope = { BindTarget = Current }
@ -34,37 +24,11 @@ namespace osu.Game.Overlays.Rankings
Current = Ruleset
};
public SpotlightSelector SpotlightSelector;
protected override Drawable CreateContent() => new FillFlowContainer
protected override Drawable CreateContent() => new CountryFilter
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new CountryFilter
{
Current = Country
},
SpotlightSelector = new SpotlightSelector
{
Current = { BindTarget = Spotlight }
}
}
Current = Country
};
protected override void LoadComplete()
{
Current.BindValueChanged(onCurrentChanged, true);
base.LoadComplete();
}
private void onCurrentChanged(ValueChangedEvent<RankingsScope> scope)
{
}
private class RankingsTitle : ScreenTitle
{
public readonly Bindable<RankingsScope> Scope = new Bindable<RankingsScope>();

View File

@ -18,8 +18,10 @@ using osu.Game.Online.API.Requests;
namespace osu.Game.Overlays.Rankings
{
public class SpotlightSelector : CompositeDrawable, IHasCurrentValue<APISpotlight>
public class SpotlightSelector : VisibilityContainer, IHasCurrentValue<APISpotlight>
{
private const int duration = 300;
private readonly Box background;
private readonly SpotlightsDropdown dropdown;
@ -37,52 +39,59 @@ namespace osu.Game.Overlays.Rankings
set => dropdown.Items = value;
}
protected override bool StartHidden => true;
private readonly InfoColumn startDateColumn;
private readonly InfoColumn endDateColumn;
private readonly InfoColumn mapCountColumn;
private readonly InfoColumn participantsColumn;
private readonly Container content;
public SpotlightSelector()
{
RelativeSizeAxes = Axes.X;
Height = 100;
AddRangeInternal(new Drawable[]
Add(content = new Container
{
background = new Box
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 },
Children = new Drawable[]
background = new Box
{
dropdown = new SpotlightsDropdown
RelativeSizeAxes = Axes.Both,
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 },
Children = new Drawable[]
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
Current = Current,
Depth = -float.MaxValue
},
new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(15, 0),
Children = new Drawable[]
dropdown = new SpotlightsDropdown
{
startDateColumn = new InfoColumn(@"Start Date"),
endDateColumn = new InfoColumn(@"End Date"),
mapCountColumn = new InfoColumn(@"Map Count"),
participantsColumn = new InfoColumn(@"Participants")
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
Current = Current,
Depth = -float.MaxValue
},
new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(15, 0),
Children = new Drawable[]
{
startDateColumn = new InfoColumn(@"Start Date"),
endDateColumn = new InfoColumn(@"End Date"),
mapCountColumn = new InfoColumn(@"Map Count"),
participantsColumn = new InfoColumn(@"Participants")
}
}
}
}
},
}
});
}
@ -100,6 +109,10 @@ namespace osu.Game.Overlays.Rankings
participantsColumn.Value = response.Spotlight.Participants?.ToString("N0");
}
protected override void PopIn() => content.FadeIn(duration, Easing.OutQuint);
protected override void PopOut() => content.FadeOut(duration, Easing.OutQuint);
private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd");
private class InfoColumn : FillFlowContainer

View File

@ -35,11 +35,12 @@ namespace osu.Game.Overlays.Rankings
private GetSpotlightRankingsRequest getRankingsRequest;
private GetSpotlightsRequest spotlightsRequest;
private readonly SpotlightSelector selector;
private readonly Container content;
private readonly DimmedLoadingLayer loading;
private SpotlightSelector selector;
private Container content;
private DimmedLoadingLayer loading;
public SpotlightsLayout()
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
@ -48,7 +49,6 @@ namespace osu.Game.Overlays.Rankings
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 20),
Children = new Drawable[]
{
selector = new SpotlightSelector
@ -65,8 +65,9 @@ namespace osu.Game.Overlays.Rankings
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Vertical = 10 }
},
loading = new DimmedLoadingLayer(),
loading = new DimmedLoadingLayer()
}
}
}
@ -77,6 +78,8 @@ namespace osu.Game.Overlays.Rankings
{
base.LoadComplete();
selector.Show();
selectedSpotlight.BindValueChanged(onSpotlightChanged);
Ruleset.BindValueChanged(onRulesetChanged);

View File

@ -14,10 +14,6 @@ using osu.Game.Online.API;
using System.Threading;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Rankings.Tables;
using osu.Game.Online.API.Requests.Responses;
using System.Linq;
using osuTK;
using osu.Game.Overlays.Direct;
namespace osu.Game.Overlays
{
@ -26,13 +22,11 @@ namespace osu.Game.Overlays
protected readonly Bindable<Country> Country = new Bindable<Country>();
protected readonly Bindable<RankingsScope> Scope = new Bindable<RankingsScope>();
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
private readonly Bindable<APISpotlight> spotlight = new Bindable<APISpotlight>();
private readonly BasicScrollContainer scrollFlow;
private readonly Container contentContainer;
private readonly DimmedLoadingLayer loading;
private readonly Box background;
private readonly RankingsOverlayHeader header;
private APIRequest lastRequest;
private CancellationTokenSource cancellationToken;
@ -40,9 +34,6 @@ namespace osu.Game.Overlays
[Resolved]
private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
public RankingsOverlay()
: base(OverlayColourScheme.Green)
{
@ -63,15 +54,14 @@ namespace osu.Game.Overlays
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
header = new RankingsOverlayHeader
new RankingsOverlayHeader
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Depth = -float.MaxValue,
Country = { BindTarget = Country },
Current = { BindTarget = Scope },
Ruleset = { BindTarget = ruleset },
Spotlight = { BindTarget = spotlight }
Ruleset = { BindTarget = ruleset }
},
new Container
{
@ -85,7 +75,7 @@ namespace osu.Game.Overlays
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Margin = new MarginPadding { Vertical = 10 }
Margin = new MarginPadding { Bottom = 10 }
},
loading = new DimmedLoadingLayer(),
}
@ -110,30 +100,25 @@ namespace osu.Game.Overlays
if (Country.Value != null)
Scope.Value = RankingsScope.Performance;
if (Scope.Value != RankingsScope.Spotlights)
Scheduler.AddOnce(loadNewContent);
Scheduler.AddOnce(loadNewContent);
}, true);
Scope.BindValueChanged(_ =>
{
spotlightsRequest?.Cancel();
// country filtering is only valid for performance scope.
if (Scope.Value != RankingsScope.Performance)
Country.Value = null;
if (Scope.Value == RankingsScope.Spotlights && !header.Spotlights.Any())
{
getSpotlights();
return;
}
Scheduler.AddOnce(loadNewContent);
}, true);
ruleset.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true);
ruleset.BindValueChanged(_ =>
{
if (Scope.Value == RankingsScope.Spotlights)
return;
spotlight.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true);
Scheduler.AddOnce(loadNewContent);
}, true);
base.LoadComplete();
}
@ -148,16 +133,6 @@ namespace osu.Game.Overlays
Country.Value = requested;
}
private GetSpotlightsRequest spotlightsRequest;
private void getSpotlights()
{
loading.Show();
spotlightsRequest = new GetSpotlightsRequest();
spotlightsRequest.Success += response => header.Spotlights = response.Spotlights;
api.Queue(spotlightsRequest);
}
private void loadNewContent()
{
loading.Show();
@ -165,6 +140,15 @@ namespace osu.Game.Overlays
cancellationToken?.Cancel();
lastRequest?.Cancel();
if (Scope.Value == RankingsScope.Spotlights)
{
loadContent(new SpotlightsLayout
{
Ruleset = { BindTarget = ruleset }
});
return;
}
var request = createScopedRequest();
lastRequest = request;
@ -174,8 +158,9 @@ namespace osu.Game.Overlays
return;
}
request.Success += () => loadContent(createContentFromResponse(request));
request.Success += () => loadContent(createTableFromResponse(request));
request.Failure += _ => loadContent(null);
api.Queue(request);
}
@ -191,15 +176,12 @@ namespace osu.Game.Overlays
case RankingsScope.Score:
return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score);
case RankingsScope.Spotlights:
return new GetSpotlightRankingsRequest(ruleset.Value, header.Spotlight.Value.Id);
}
return null;
}
private Drawable createContentFromResponse(APIRequest request)
private Drawable createTableFromResponse(APIRequest request)
{
switch (request)
{
@ -217,42 +199,11 @@ namespace osu.Game.Overlays
case GetCountryRankingsRequest countryRequest:
return new CountriesTable(1, countryRequest.Result.Countries);
case GetSpotlightRankingsRequest spotlightRequest:
return getSpotlightContent(spotlightRequest.Result);
}
return null;
}
private Drawable getSpotlightContent(GetSpotlightRankingsResponse response)
{
header.SpotlightSelector.ShowInfo(response);
return new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 20),
Children = new Drawable[]
{
new ScoresTable(1, response.Users),
new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Spacing = new Vector2(10),
Children = response.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets))
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
}).ToList()
}
}
};
}
private void loadContent(Drawable content)
{
scrollFlow.ScrollToStart();
@ -264,10 +215,10 @@ namespace osu.Game.Overlays
return;
}
LoadComponentAsync(content, t =>
LoadComponentAsync(content, loaded =>
{
loading.Hide();
contentContainer.Child = content;
contentContainer.Child = loaded;
}, (cancellationToken = new CancellationTokenSource()).Token);
}
}