mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 10:12:54 +08:00
Implement TabbableOnlineOverlay component
This commit is contained in:
parent
70420b56d3
commit
c6b0f3c247
@ -2,115 +2,35 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.Dashboard;
|
||||
using osu.Game.Overlays.Dashboard.Friends;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class DashboardOverlay : OnlineOverlay<DashboardOverlayHeader>
|
||||
public class DashboardOverlay : TabbableOnlineOverlay<DashboardOverlayHeader, DashboardOverlayTabs>
|
||||
{
|
||||
private CancellationTokenSource cancellationToken;
|
||||
|
||||
public DashboardOverlay()
|
||||
: base(OverlayColourScheme.Purple)
|
||||
{
|
||||
}
|
||||
|
||||
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAPIProvider api)
|
||||
{
|
||||
apiState.BindTo(api.State);
|
||||
apiState.BindValueChanged(onlineStateChanged, true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Header.Current.BindValueChanged(onTabChanged);
|
||||
}
|
||||
|
||||
protected override DashboardOverlayHeader CreateHeader() => new DashboardOverlayHeader();
|
||||
|
||||
private bool displayUpdateRequired = true;
|
||||
|
||||
protected override void PopIn()
|
||||
protected override void CreateDisplayToLoad(DashboardOverlayTabs tab)
|
||||
{
|
||||
base.PopIn();
|
||||
|
||||
// We don't want to create a new display on every call, only when exiting from fully closed state.
|
||||
if (displayUpdateRequired)
|
||||
{
|
||||
Header.Current.TriggerChange();
|
||||
displayUpdateRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PopOutComplete()
|
||||
{
|
||||
base.PopOutComplete();
|
||||
loadDisplay(Empty());
|
||||
displayUpdateRequired = true;
|
||||
}
|
||||
|
||||
private void loadDisplay(Drawable display)
|
||||
{
|
||||
ScrollFlow.ScrollToStart();
|
||||
|
||||
LoadComponentAsync(display, loaded =>
|
||||
{
|
||||
if (API.IsLoggedIn)
|
||||
Loading.Hide();
|
||||
|
||||
Child = loaded;
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
|
||||
private void onTabChanged(ValueChangedEvent<DashboardOverlayTabs> tab)
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
Loading.Show();
|
||||
|
||||
if (!API.IsLoggedIn)
|
||||
{
|
||||
loadDisplay(Empty());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tab.NewValue)
|
||||
switch (tab)
|
||||
{
|
||||
case DashboardOverlayTabs.Friends:
|
||||
loadDisplay(new FriendDisplay());
|
||||
LoadDisplay(new FriendDisplay());
|
||||
break;
|
||||
|
||||
case DashboardOverlayTabs.CurrentlyPlaying:
|
||||
loadDisplay(new CurrentlyPlayingDisplay());
|
||||
LoadDisplay(new CurrentlyPlayingDisplay());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Display for {tab.NewValue} tab is not implemented");
|
||||
throw new NotImplementedException($"Display for {tab} tab is not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
||||
{
|
||||
if (State.Value == Visibility.Hidden)
|
||||
return;
|
||||
|
||||
Header.Current.TriggerChange();
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,20 +8,18 @@ using osu.Game.Overlays.Rankings;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Online.API;
|
||||
using System.Threading;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.Rankings.Tables;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class RankingsOverlay : OnlineOverlay<RankingsOverlayHeader>
|
||||
public class RankingsOverlay : TabbableOnlineOverlay<RankingsOverlayHeader, RankingsScope>
|
||||
{
|
||||
protected Bindable<Country> Country => Header.Country;
|
||||
|
||||
protected Bindable<RankingsScope> Scope => Header.Current;
|
||||
|
||||
private APIRequest lastRequest;
|
||||
private CancellationTokenSource cancellationToken;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
@ -34,11 +32,6 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -54,6 +47,8 @@ namespace osu.Game.Overlays
|
||||
Scheduler.AddOnce(loadNewContent);
|
||||
});
|
||||
|
||||
// Unbind events from scope so base class event will not be called
|
||||
Scope.UnbindEvents();
|
||||
Scope.BindValueChanged(_ =>
|
||||
{
|
||||
// country filtering is only valid for performance scope.
|
||||
@ -70,8 +65,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
Scheduler.AddOnce(loadNewContent);
|
||||
});
|
||||
|
||||
Scheduler.AddOnce(loadNewContent);
|
||||
}
|
||||
|
||||
protected override RankingsOverlayHeader CreateHeader() => new RankingsOverlayHeader();
|
||||
@ -92,16 +85,13 @@ namespace osu.Game.Overlays
|
||||
Show();
|
||||
}
|
||||
|
||||
private void loadNewContent()
|
||||
protected override void CreateDisplayToLoad(RankingsScope tab)
|
||||
{
|
||||
Loading.Show();
|
||||
|
||||
cancellationToken?.Cancel();
|
||||
lastRequest?.Cancel();
|
||||
|
||||
if (Scope.Value == RankingsScope.Spotlights)
|
||||
{
|
||||
loadContent(new SpotlightsLayout
|
||||
LoadDisplay(new SpotlightsLayout
|
||||
{
|
||||
Ruleset = { BindTarget = ruleset }
|
||||
});
|
||||
@ -113,12 +103,12 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (request == null)
|
||||
{
|
||||
loadContent(null);
|
||||
LoadDisplay(Empty());
|
||||
return;
|
||||
}
|
||||
|
||||
request.Success += () => Schedule(() => loadContent(createTableFromResponse(request)));
|
||||
request.Failure += _ => Schedule(() => loadContent(null));
|
||||
request.Success += () => Schedule(() => LoadDisplay(createTableFromResponse(request)));
|
||||
request.Failure += _ => Schedule(() => LoadDisplay(Empty()));
|
||||
|
||||
api.Queue(request);
|
||||
}
|
||||
@ -163,29 +153,11 @@ namespace osu.Game.Overlays
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadContent(Drawable content)
|
||||
{
|
||||
ScrollFlow.ScrollToStart();
|
||||
|
||||
if (content == null)
|
||||
{
|
||||
Clear();
|
||||
Loading.Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
LoadComponentAsync(content, loaded =>
|
||||
{
|
||||
Loading.Hide();
|
||||
Child = loaded;
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
private void loadNewContent() => OnTabChanged(Scope.Value);
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
lastRequest?.Cancel();
|
||||
cancellationToken?.Cancel();
|
||||
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
}
|
||||
|
101
osu.Game/Overlays/TabbableOnlineOverlay.cs
Normal file
101
osu.Game/Overlays/TabbableOnlineOverlay.cs
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.API;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public abstract class TabbableOnlineOverlay<THeader, TEnum> : OnlineOverlay<THeader>
|
||||
where THeader : TabControlOverlayHeader<TEnum>
|
||||
{
|
||||
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
||||
|
||||
private CancellationTokenSource cancellationToken;
|
||||
private bool displayUpdateRequired = true;
|
||||
|
||||
protected TabbableOnlineOverlay(OverlayColourScheme colourScheme)
|
||||
: base(colourScheme)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAPIProvider api)
|
||||
{
|
||||
apiState.BindTo(api.State);
|
||||
apiState.BindValueChanged(onlineStateChanged, true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Header.Current.BindValueChanged(tab => OnTabChanged(tab.NewValue));
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
base.PopIn();
|
||||
|
||||
// We don't want to create a new display on every call, only when exiting from fully closed state.
|
||||
if (displayUpdateRequired)
|
||||
{
|
||||
Header.Current.TriggerChange();
|
||||
displayUpdateRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PopOutComplete()
|
||||
{
|
||||
base.PopOutComplete();
|
||||
LoadDisplay(Empty());
|
||||
displayUpdateRequired = true;
|
||||
}
|
||||
|
||||
protected void LoadDisplay(Drawable display)
|
||||
{
|
||||
ScrollFlow.ScrollToStart();
|
||||
|
||||
LoadComponentAsync(display, loaded =>
|
||||
{
|
||||
if (API.IsLoggedIn)
|
||||
Loading.Hide();
|
||||
|
||||
Child = loaded;
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
|
||||
protected void OnTabChanged(TEnum tab)
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
Loading.Show();
|
||||
|
||||
if (!API.IsLoggedIn)
|
||||
{
|
||||
LoadDisplay(Empty());
|
||||
return;
|
||||
}
|
||||
|
||||
CreateDisplayToLoad(tab);
|
||||
}
|
||||
|
||||
protected abstract void CreateDisplayToLoad(TEnum tab);
|
||||
|
||||
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
||||
{
|
||||
if (State.Value == Visibility.Hidden)
|
||||
return;
|
||||
|
||||
Header.Current.TriggerChange();
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user