mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Merge branch 'master' into samah-ios
This commit is contained in:
commit
436fbc7ffe
@ -21,7 +21,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
base.AddInternal(shakeContainer = new ShakeContainer { RelativeSizeAxes = Axes.Both });
|
||||
base.AddInternal(shakeContainer = new ShakeContainer
|
||||
{
|
||||
ShakeDuration = 30,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
});
|
||||
Alpha = 0;
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.A, OsuAction.LeftButton),
|
||||
new KeyBinding(InputKey.S, OsuAction.RightButton),
|
||||
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
|
||||
new KeyBinding(InputKey.X, OsuAction.RightButton),
|
||||
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
|
||||
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
|
||||
};
|
||||
|
32
osu.Game.Tests/Visual/TestCaseAccountCreationOverlay.cs
Normal file
32
osu.Game.Tests/Visual/TestCaseAccountCreationOverlay.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.AccountCreation;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseAccountCreationOverlay : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ErrorTextFlowContainer),
|
||||
typeof(AccountCreationBackground),
|
||||
typeof(ScreenEntry),
|
||||
typeof(ScreenWarning),
|
||||
typeof(ScreenWelcome),
|
||||
typeof(AccountCreationScreen),
|
||||
};
|
||||
|
||||
public TestCaseAccountCreationOverlay()
|
||||
{
|
||||
var accountCreation = new AccountCreationOverlay();
|
||||
Child = accountCreation;
|
||||
|
||||
accountCreation.State = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseDrawableDate : OsuTestCase
|
||||
{
|
||||
public TestCaseDrawableDate()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(60))),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(55))),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(50))),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(60))),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(65))),
|
||||
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(70))),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class PokeyDrawableDate : CompositeDrawable
|
||||
{
|
||||
public PokeyDrawableDate(DateTimeOffset date)
|
||||
{
|
||||
const float box_size = 10;
|
||||
|
||||
DrawableDate drawableDate;
|
||||
Box flash;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
flash = new Box
|
||||
{
|
||||
Colour = Color4.Yellow,
|
||||
Size = new Vector2(box_size),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Alpha = 0
|
||||
},
|
||||
drawableDate = new DrawableDate(date)
|
||||
{
|
||||
X = box_size + 2,
|
||||
}
|
||||
};
|
||||
|
||||
drawableDate.Current.ValueChanged += v => flash.FadeOutFromOne(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using osu.Framework.Allocation;
|
||||
using osuTK;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
@ -36,7 +37,7 @@ namespace osu.Game.Tests.Visual
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Size = new Vector2(550f, 450f),
|
||||
Scope = LeaderboardScope.Global,
|
||||
Scope = BeatmapLeaderboardScope.Global,
|
||||
});
|
||||
|
||||
AddStep(@"New Scores", newScores);
|
||||
@ -275,7 +276,7 @@ namespace osu.Game.Tests.Visual
|
||||
};
|
||||
}
|
||||
|
||||
private class FailableLeaderboard : Leaderboard
|
||||
private class FailableLeaderboard : BeatmapLeaderboard
|
||||
{
|
||||
public void SetRetrievalState(PlaceholderState state)
|
||||
{
|
||||
|
@ -8,7 +8,9 @@ using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -23,8 +25,8 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(ScoreInfo),
|
||||
typeof(Results),
|
||||
typeof(ResultsPage),
|
||||
typeof(ResultsPageScore),
|
||||
typeof(ResultsPageRanking)
|
||||
typeof(ScoreResultsPage),
|
||||
typeof(RankingResultsPage)
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -41,7 +43,7 @@ namespace osu.Game.Tests.Visual
|
||||
if (beatmapInfo != null)
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||
|
||||
Add(new Results(new ScoreInfo
|
||||
Add(new SoloResults(new ScoreInfo
|
||||
{
|
||||
TotalScore = 2845370,
|
||||
Accuracy = 0.98,
|
||||
|
@ -68,31 +68,33 @@ namespace osu.Game.Tests.Visual
|
||||
chatDisplay.Channel.Value = testChannel;
|
||||
chatDisplay2.Channel.Value = testChannel;
|
||||
|
||||
AddStep("message from admin", () => testChannel.AddLocalEcho(new LocalEchoMessage
|
||||
int sequence = 0;
|
||||
|
||||
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||
{
|
||||
Sender = admin,
|
||||
Content = "I am a wang!"
|
||||
}));
|
||||
|
||||
AddStep("message from team red", () => testChannel.AddLocalEcho(new LocalEchoMessage
|
||||
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||
{
|
||||
Sender = redUser,
|
||||
Content = "I am team red."
|
||||
}));
|
||||
|
||||
AddStep("message from team red", () => testChannel.AddLocalEcho(new LocalEchoMessage
|
||||
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||
{
|
||||
Sender = redUser,
|
||||
Content = "I plan to win!"
|
||||
}));
|
||||
|
||||
AddStep("message from team blue", () => testChannel.AddLocalEcho(new LocalEchoMessage
|
||||
AddStep("message from team blue", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||
{
|
||||
Sender = blueUser,
|
||||
Content = "Not on my watch. Prepare to eat saaaaaaaaaand. Lots and lots of saaaaaaand."
|
||||
}));
|
||||
|
||||
AddStep("message from admin", () => testChannel.AddLocalEcho(new LocalEchoMessage
|
||||
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||
{
|
||||
Sender = admin,
|
||||
Content = "Okay okay, calm down guys. Let's do this!"
|
||||
|
@ -26,7 +26,6 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
private PreviewTrackManager previewTrackManager;
|
||||
|
||||
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
|
@ -11,29 +11,43 @@ namespace osu.Game.Graphics.Containers
|
||||
/// </summary>
|
||||
public class ShakeContainer : Container
|
||||
{
|
||||
/// <summary>
|
||||
/// The length of a single shake.
|
||||
/// </summary>
|
||||
public float ShakeDuration = 80;
|
||||
|
||||
/// <summary>
|
||||
/// Total number of shakes. May be shortened if possible.
|
||||
/// </summary>
|
||||
public float TotalShakes = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Pixels of displacement per shake.
|
||||
/// </summary>
|
||||
public float ShakeMagnitude = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Shake the contents of this container.
|
||||
/// </summary>
|
||||
/// <param name="maximumLength">The maximum length the shake should last.</param>
|
||||
public void Shake(double maximumLength)
|
||||
public void Shake(double? maximumLength = null)
|
||||
{
|
||||
const float shake_amount = 8;
|
||||
const float shake_duration = 30;
|
||||
|
||||
// if we don't have enough time, don't bother shaking.
|
||||
if (maximumLength < shake_duration * 2)
|
||||
if (maximumLength < ShakeDuration * 2)
|
||||
return;
|
||||
|
||||
var sequence = this.MoveToX(shake_amount, shake_duration / 2, Easing.OutSine).Then()
|
||||
.MoveToX(-shake_amount, shake_duration, Easing.InOutSine).Then();
|
||||
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
|
||||
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
|
||||
|
||||
// if we don't have enough time for the second shake, skip it.
|
||||
if (maximumLength > shake_duration * 4)
|
||||
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
|
||||
sequence = sequence
|
||||
.MoveToX(shake_amount, shake_duration, Easing.InOutSine).Then()
|
||||
.MoveToX(-shake_amount, shake_duration, Easing.InOutSine).Then();
|
||||
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
|
||||
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
|
||||
|
||||
sequence.MoveToX(0, shake_duration / 2, Easing.InSine);
|
||||
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using Humanizer;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
@ -11,13 +12,27 @@ namespace osu.Game.Graphics
|
||||
{
|
||||
public class DrawableDate : OsuSpriteText, IHasTooltip
|
||||
{
|
||||
protected readonly DateTimeOffset Date;
|
||||
private DateTimeOffset date;
|
||||
|
||||
public DateTimeOffset Date
|
||||
{
|
||||
get => date;
|
||||
set
|
||||
{
|
||||
if (date == value)
|
||||
return;
|
||||
date = value.ToLocalTime();
|
||||
|
||||
if (LoadState >= LoadState.Ready)
|
||||
updateTime();
|
||||
}
|
||||
}
|
||||
|
||||
public DrawableDate(DateTimeOffset date)
|
||||
{
|
||||
Font = "Exo2.0-RegularItalic";
|
||||
|
||||
Date = date.ToLocalTime();
|
||||
Date = date;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -39,14 +54,14 @@ namespace osu.Game.Graphics
|
||||
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
||||
|
||||
double timeUntilNextUpdate = 1000;
|
||||
if (diffToNow.TotalSeconds > 60)
|
||||
if (Math.Abs(diffToNow.TotalSeconds) > 120)
|
||||
{
|
||||
timeUntilNextUpdate *= 60;
|
||||
if (diffToNow.TotalMinutes > 60)
|
||||
if (Math.Abs(diffToNow.TotalMinutes) > 120)
|
||||
{
|
||||
timeUntilNextUpdate *= 60;
|
||||
|
||||
if (diffToNow.TotalHours > 24)
|
||||
if (Math.Abs(diffToNow.TotalHours) > 48)
|
||||
timeUntilNextUpdate *= 24;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// A loading spinner.
|
||||
/// </summary>
|
||||
public class LoadingAnimation : VisibilityContainer
|
||||
{
|
||||
private readonly SpriteIcon spinner;
|
||||
|
56
osu.Game/Graphics/UserInterface/ProcessingOverlay.cs
Normal file
56
osu.Game/Graphics/UserInterface/ProcessingOverlay.cs
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// An overlay that will consume all available space and block input when required.
|
||||
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
|
||||
/// </summary>
|
||||
public class ProcessingOverlay : VisibilityContainer
|
||||
{
|
||||
private const float transition_duration = 200;
|
||||
|
||||
public ProcessingOverlay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = Color4.Black,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.9f,
|
||||
},
|
||||
new LoadingAnimation { State = Visibility.Visible }
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool Handle(UIEvent e)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
this.FadeIn(transition_duration * 2, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
this.FadeOut(transition_duration, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Logging;
|
||||
@ -159,7 +161,7 @@ namespace osu.Game.Online.API
|
||||
//hard bail if we can't get a valid access token.
|
||||
if (authentication.RequestAccessToken() == null)
|
||||
{
|
||||
Logout(false);
|
||||
Logout();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -188,6 +190,39 @@ namespace osu.Game.Online.API
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
|
||||
{
|
||||
Debug.Assert(State == APIState.Offline);
|
||||
|
||||
var req = new RegistrationRequest
|
||||
{
|
||||
Url = $@"{Endpoint}/users",
|
||||
Method = HttpMethod.Post,
|
||||
Username = username,
|
||||
Email = email,
|
||||
Password = password
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
req.Perform();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JObject.Parse(req.ResponseString).SelectToken("form_error", true).ToObject<RegistrationRequest.RegistrationRequestErrors>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if we couldn't deserialize the error message let's throw the original exception outwards.
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a single API request.
|
||||
/// Ensures all exceptions are caught and dealt with correctly.
|
||||
@ -258,7 +293,7 @@ namespace osu.Game.Online.API
|
||||
switch (statusCode)
|
||||
{
|
||||
case HttpStatusCode.Unauthorized:
|
||||
Logout(false);
|
||||
Logout();
|
||||
return true;
|
||||
case HttpStatusCode.RequestTimeout:
|
||||
failureCount++;
|
||||
@ -307,10 +342,9 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
public void Logout(bool clearUsername = true)
|
||||
public void Logout()
|
||||
{
|
||||
flushQueue();
|
||||
if (clearUsername) ProvidedUsername = null;
|
||||
password = null;
|
||||
authentication.Clear();
|
||||
LocalUser.Value = createGuestUser();
|
||||
|
41
osu.Game/Online/API/RegistrationRequest.cs
Normal file
41
osu.Game/Online/API/RegistrationRequest.cs
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.IO.Network;
|
||||
|
||||
namespace osu.Game.Online.API
|
||||
{
|
||||
public class RegistrationRequest : WebRequest
|
||||
{
|
||||
internal string Username;
|
||||
internal string Email;
|
||||
internal string Password;
|
||||
|
||||
protected override void PrePerform()
|
||||
{
|
||||
AddParameter("user[username]", Username);
|
||||
AddParameter("user[user_email]", Email);
|
||||
AddParameter("user[password]", Password);
|
||||
|
||||
base.PrePerform();
|
||||
}
|
||||
|
||||
public class RegistrationRequestErrors
|
||||
{
|
||||
public UserErrors User;
|
||||
|
||||
public class UserErrors
|
||||
{
|
||||
[JsonProperty("username")]
|
||||
public string[] Username;
|
||||
|
||||
[JsonProperty("user_email")]
|
||||
public string[] Email;
|
||||
|
||||
[JsonProperty("password")]
|
||||
public string[] Password;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,15 +13,15 @@ namespace osu.Game.Online.API.Requests
|
||||
public class GetScoresRequest : APIRequest<APIScores>
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private readonly LeaderboardScope scope;
|
||||
private readonly BeatmapLeaderboardScope scope;
|
||||
private readonly RulesetInfo ruleset;
|
||||
|
||||
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, LeaderboardScope scope = LeaderboardScope.Global)
|
||||
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global)
|
||||
{
|
||||
if (!beatmap.OnlineBeatmapID.HasValue)
|
||||
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
|
||||
|
||||
if (scope == LeaderboardScope.Local)
|
||||
if (scope == BeatmapLeaderboardScope.Local)
|
||||
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
|
||||
|
||||
this.beatmap = beatmap;
|
||||
|
@ -1,19 +1,15 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osuTK;
|
||||
using osu.Game.Overlays.Chat;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
@ -23,22 +19,27 @@ namespace osu.Game.Online.Chat
|
||||
/// </summary>
|
||||
public class StandAloneChatDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly bool postingTextbox;
|
||||
|
||||
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
|
||||
|
||||
private readonly FillFlowContainer messagesFlow;
|
||||
|
||||
private Channel lastChannel;
|
||||
|
||||
private readonly FocusedTextBox textbox;
|
||||
|
||||
protected ChannelManager ChannelManager;
|
||||
|
||||
private ScrollContainer scroll;
|
||||
|
||||
private DrawableChannel drawableChannel;
|
||||
|
||||
private const float textbox_height = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new instance.
|
||||
/// </summary>
|
||||
/// <param name="postingTextbox">Whether a textbox for posting new messages should be displayed.</param>
|
||||
public StandAloneChatDisplay(bool postingTextbox = false)
|
||||
{
|
||||
this.postingTextbox = postingTextbox;
|
||||
CornerRadius = 10;
|
||||
Masking = true;
|
||||
|
||||
@ -50,23 +51,10 @@ namespace osu.Game.Online.Chat
|
||||
Alpha = 0.8f,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
messagesFlow = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
LayoutEasing = Easing.Out,
|
||||
LayoutDuration = 500,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Direction = FillDirection.Vertical
|
||||
}
|
||||
};
|
||||
|
||||
const float textbox_height = 30;
|
||||
|
||||
if (postingTextbox)
|
||||
{
|
||||
messagesFlow.Y -= textbox_height;
|
||||
AddInternal(textbox = new FocusedTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -117,112 +105,43 @@ namespace osu.Game.Online.Chat
|
||||
this.MoveToY(100, 500, Easing.In);
|
||||
}
|
||||
|
||||
protected virtual Drawable CreateMessage(Message message)
|
||||
{
|
||||
return new StandAloneMessage(message);
|
||||
}
|
||||
protected virtual ChatLine CreateMessage(Message message) => new StandAloneMessage(message);
|
||||
|
||||
private void channelChanged(Channel channel)
|
||||
{
|
||||
if (lastChannel != null)
|
||||
lastChannel.NewMessagesArrived -= newMessages;
|
||||
|
||||
lastChannel = channel;
|
||||
messagesFlow.Clear();
|
||||
drawableChannel?.Expire();
|
||||
|
||||
if (channel == null) return;
|
||||
|
||||
channel.NewMessagesArrived += newMessages;
|
||||
|
||||
newMessages(channel.Messages);
|
||||
AddInternal(drawableChannel = new StandAloneDrawableChannel(channel)
|
||||
{
|
||||
CreateChatLineAction = CreateMessage,
|
||||
Padding = new MarginPadding { Bottom = postingTextbox ? textbox_height : 0 }
|
||||
});
|
||||
}
|
||||
|
||||
private void newMessages(IEnumerable<Message> messages)
|
||||
protected class StandAloneDrawableChannel : DrawableChannel
|
||||
{
|
||||
var excessChildren = messagesFlow.Children.Count - 10;
|
||||
if (excessChildren > 0)
|
||||
foreach (var c in messagesFlow.Children.Take(excessChildren))
|
||||
c.Expire();
|
||||
public Func<Message,ChatLine> CreateChatLineAction;
|
||||
|
||||
foreach (var message in messages)
|
||||
protected override ChatLine CreateChatLine(Message m) => CreateChatLineAction(m);
|
||||
|
||||
public StandAloneDrawableChannel(Channel channel)
|
||||
: base(channel)
|
||||
{
|
||||
var formatted = MessageFormatter.FormatMessage(message);
|
||||
var drawable = CreateMessage(formatted);
|
||||
drawable.Y = messagesFlow.Height;
|
||||
messagesFlow.Add(drawable);
|
||||
ChatLineFlow.Padding = new MarginPadding { Horizontal = 0 };
|
||||
}
|
||||
}
|
||||
|
||||
protected class StandAloneMessage : CompositeDrawable
|
||||
protected class StandAloneMessage : ChatLine
|
||||
{
|
||||
protected readonly Message Message;
|
||||
protected OsuSpriteText SenderText;
|
||||
protected Circle ColourBox;
|
||||
protected override float TextSize => 15;
|
||||
|
||||
public StandAloneMessage(Message message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
protected override float HorizontalPadding => 10;
|
||||
protected override float MessagePadding => 120;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
public StandAloneMessage(Message message) : base(message)
|
||||
{
|
||||
Margin = new MarginPadding(3);
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.2f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
SenderText = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Bold",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Text = Message.Sender.ToString()
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(8, OsuSpriteText.FONT_SIZE),
|
||||
Margin = new MarginPadding { Horizontal = 3 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
ColourBox = new Circle
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(8)
|
||||
}
|
||||
}
|
||||
},
|
||||
new OsuTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Width = 0.5f,
|
||||
Text = Message.DisplayContent
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(Message.Sender.Colour))
|
||||
SenderText.Colour = ColourBox.Colour = OsuColour.FromHex(Message.Sender.Colour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,14 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public class DrawableRank : Container
|
||||
{
|
@ -3,27 +3,22 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public class Leaderboard : Container
|
||||
public abstract class Leaderboard<TScope, ScoreInfo> : Container
|
||||
{
|
||||
private const double fade_duration = 300;
|
||||
|
||||
@ -32,10 +27,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
||||
|
||||
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
public Action<ScoreInfo> ScoreSelected;
|
||||
|
||||
private readonly LoadingAnimation loading;
|
||||
|
||||
private ScheduledDelegate showScoresDelegate;
|
||||
@ -70,7 +61,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||
ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) })
|
||||
ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1))
|
||||
};
|
||||
|
||||
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||
@ -96,18 +87,18 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardScope scope;
|
||||
private TScope scope;
|
||||
|
||||
public LeaderboardScope Scope
|
||||
public TScope Scope
|
||||
{
|
||||
get { return scope; }
|
||||
set
|
||||
{
|
||||
if (value == scope)
|
||||
if (value.Equals(scope))
|
||||
return;
|
||||
|
||||
scope = value;
|
||||
updateScores();
|
||||
UpdateScores();
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +128,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
case PlaceholderState.NetworkFailure:
|
||||
replacePlaceholder(new RetrievalFailurePlaceholder
|
||||
{
|
||||
OnRetry = updateScores,
|
||||
OnRetry = UpdateScores,
|
||||
});
|
||||
break;
|
||||
case PlaceholderState.Unavailable:
|
||||
@ -159,7 +150,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
public Leaderboard()
|
||||
protected Leaderboard()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -177,36 +168,14 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
|
||||
private APIAccess api;
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; }
|
||||
|
||||
private ScheduledDelegate pendingUpdateScores;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
if (beatmap == value)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
Scores = null;
|
||||
|
||||
updateScores();
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(APIAccess api, IBindable<RulesetInfo> parentRuleset)
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
ruleset.BindTo(parentRuleset);
|
||||
ruleset.ValueChanged += _ => updateScores();
|
||||
|
||||
if (api != null)
|
||||
api.OnStateChange += handleApiStateChange;
|
||||
}
|
||||
@ -219,21 +188,17 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
api.OnStateChange -= handleApiStateChange;
|
||||
}
|
||||
|
||||
public void RefreshScores() => updateScores();
|
||||
public void RefreshScores() => UpdateScores();
|
||||
|
||||
private GetScoresRequest getScoresRequest;
|
||||
private APIRequest getScoresRequest;
|
||||
|
||||
private void handleApiStateChange(APIState oldState, APIState newState)
|
||||
{
|
||||
if (Scope == LeaderboardScope.Local)
|
||||
// No need to respond to API state change while current scope is local
|
||||
return;
|
||||
|
||||
if (newState == APIState.Online)
|
||||
updateScores();
|
||||
UpdateScores();
|
||||
}
|
||||
|
||||
private void updateScores()
|
||||
protected void UpdateScores()
|
||||
{
|
||||
// don't display any scores or placeholder until the first Scores_Set has been called.
|
||||
// this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished.
|
||||
@ -245,40 +210,23 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
pendingUpdateScores?.Cancel();
|
||||
pendingUpdateScores = Schedule(() =>
|
||||
{
|
||||
if (Scope == LeaderboardScope.Local)
|
||||
{
|
||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Beatmap?.OnlineBeatmapID == null)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.Unavailable;
|
||||
return;
|
||||
}
|
||||
|
||||
if (api?.IsLoggedIn != true)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotSupporter;
|
||||
return;
|
||||
}
|
||||
|
||||
PlaceholderState = PlaceholderState.Retrieving;
|
||||
loading.Show();
|
||||
|
||||
getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||
getScoresRequest.Success += r => Schedule(() =>
|
||||
getScoresRequest = FetchScores(scores => Schedule(() =>
|
||||
{
|
||||
Scores = r.Scores;
|
||||
Scores = scores;
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
});
|
||||
}));
|
||||
|
||||
if (getScoresRequest == null)
|
||||
return;
|
||||
|
||||
getScoresRequest.Failure += e => Schedule(() =>
|
||||
{
|
||||
@ -292,6 +240,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback);
|
||||
|
||||
private Placeholder currentPlaceholder;
|
||||
|
||||
private void replacePlaceholder(Placeholder placeholder)
|
||||
@ -344,5 +294,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract LeaderboardScore CreateDrawableScore(ScoreInfo model, int index);
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -17,35 +16,40 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public class LeaderboardScore : OsuClickableContainer
|
||||
{
|
||||
public static readonly float HEIGHT = 60;
|
||||
|
||||
public readonly int RankPosition;
|
||||
public readonly ScoreInfo Score;
|
||||
|
||||
public const float HEIGHT = 60;
|
||||
|
||||
private const float corner_radius = 5;
|
||||
private const float edge_margin = 5;
|
||||
private const float background_alpha = 0.25f;
|
||||
private const float rank_width = 30;
|
||||
|
||||
protected Container RankContainer { get; private set; }
|
||||
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
private Box background;
|
||||
private Container content;
|
||||
private Drawable avatar;
|
||||
private DrawableRank scoreRank;
|
||||
private Drawable scoreRank;
|
||||
private OsuSpriteText nameLabel;
|
||||
private GlowingSpriteText scoreLabel;
|
||||
private ScoreComponentLabel maxCombo;
|
||||
private ScoreComponentLabel accuracy;
|
||||
private Container flagBadgeContainer;
|
||||
private FillFlowContainer<ModIcon> modsContainer;
|
||||
|
||||
private List<ScoreComponentLabel> statisticsLabels;
|
||||
|
||||
public LeaderboardScore(ScoreInfo score, int rank)
|
||||
{
|
||||
Score = score;
|
||||
this.score = score;
|
||||
RankPosition = rank;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
@ -55,6 +59,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var user = score.User;
|
||||
|
||||
statisticsLabels = GetStatistics(score).Select(s => new ScoreComponentLabel(s)).ToList();
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
@ -102,7 +110,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Children = new[]
|
||||
{
|
||||
avatar = new DelayedLoadWrapper(
|
||||
new Avatar(Score.User)
|
||||
new Avatar(user)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = corner_radius,
|
||||
@ -128,7 +136,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
nameLabel = new OsuSpriteText
|
||||
{
|
||||
Text = Score.User.Username,
|
||||
Text = user.Username,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
TextSize = 23,
|
||||
},
|
||||
@ -149,7 +157,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableFlag(Score.User?.Country)
|
||||
new DrawableFlag(user.Country)
|
||||
{
|
||||
Width = 30,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
@ -164,11 +172,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0f),
|
||||
Margin = new MarginPadding { Left = edge_margin },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
|
||||
},
|
||||
Children = statisticsLabels
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -183,17 +187,17 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
|
||||
new Container
|
||||
scoreLabel = new GlowingSpriteText(score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
|
||||
RankContainer = new Container
|
||||
{
|
||||
Size = new Vector2(40f, 20f),
|
||||
Children = new[]
|
||||
{
|
||||
scoreRank = new DrawableRank(Score.Rank)
|
||||
scoreRank = new DrawableRank(score.Rank)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(40f),
|
||||
Size = new Vector2(40f)
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -205,7 +209,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Origin = Anchor.BottomRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
ChildrenEnumerable = Score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
||||
ChildrenEnumerable = score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -216,7 +220,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
|
||||
foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, modsContainer }.Concat(statisticsLabels))
|
||||
d.FadeOut();
|
||||
|
||||
Alpha = 0;
|
||||
@ -243,7 +247,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
using (BeginDelayedSequence(50, true))
|
||||
{
|
||||
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
|
||||
var drawables = new Drawable[] { flagBadgeContainer, modsContainer }.Concat(statisticsLabels).ToArray();
|
||||
for (int i = 0; i < drawables.Length; i++)
|
||||
drawables[i].FadeIn(100 + i * 50);
|
||||
}
|
||||
@ -251,6 +255,12 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<LeaderboardScoreStatistic> GetStatistics(ScoreInfo model) => new[]
|
||||
{
|
||||
new LeaderboardScoreStatistic(FontAwesome.fa_link, "Max Combo", model.MaxCombo.ToString()),
|
||||
new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy))
|
||||
};
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
background.FadeTo(0.5f, 300, Easing.OutQuint);
|
||||
@ -321,11 +331,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
public string TooltipText => name;
|
||||
|
||||
public ScoreComponentLabel(FontAwesome icon, string value, string name)
|
||||
public ScoreComponentLabel(LeaderboardScoreStatistic statistic)
|
||||
{
|
||||
this.name = name;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Width = 60;
|
||||
name = statistic.Name;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Child = content = new FillFlowContainer
|
||||
{
|
||||
@ -356,11 +365,11 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(icon_size - 6),
|
||||
Colour = OsuColour.FromHex(@"a4edff"),
|
||||
Icon = icon,
|
||||
Icon = statistic.Icon,
|
||||
},
|
||||
},
|
||||
},
|
||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
new GlowingSpriteText(statistic.Value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
@ -369,5 +378,19 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class LeaderboardScoreStatistic
|
||||
{
|
||||
public FontAwesome Icon;
|
||||
public string Value;
|
||||
public string Name;
|
||||
|
||||
public LeaderboardScoreStatistic(FontAwesome icon, string name, string value)
|
||||
{
|
||||
Icon = icon;
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public class MessagePlaceholder : Placeholder
|
||||
{
|
@ -5,7 +5,7 @@ using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public enum PlaceholderState
|
||||
{
|
@ -8,7 +8,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public class RetrievalFailurePlaceholder : Placeholder
|
||||
{
|
@ -61,6 +61,8 @@ namespace osu.Game
|
||||
|
||||
private DialogOverlay dialogOverlay;
|
||||
|
||||
private AccountCreationOverlay accountCreation;
|
||||
|
||||
private DirectOverlay direct;
|
||||
|
||||
private SocialOverlay social;
|
||||
@ -185,7 +187,13 @@ namespace osu.Game
|
||||
}
|
||||
|
||||
private ExternalLinkOpener externalLinkOpener;
|
||||
public void OpenUrlExternally(string url) => externalLinkOpener.OpenUrlExternally(url);
|
||||
public void OpenUrlExternally(string url)
|
||||
{
|
||||
if (url.StartsWith("/"))
|
||||
url = $"{API.Endpoint}{url}";
|
||||
|
||||
externalLinkOpener.OpenUrlExternally(url);
|
||||
}
|
||||
|
||||
private ScheduledDelegate scoreLoad;
|
||||
|
||||
@ -400,11 +408,21 @@ namespace osu.Game
|
||||
Origin = Anchor.TopRight,
|
||||
}, overlayContent.Add);
|
||||
|
||||
loadComponentSingleFile(dialogOverlay = new DialogOverlay
|
||||
loadComponentSingleFile(accountCreation = new AccountCreationOverlay
|
||||
{
|
||||
Depth = -6,
|
||||
}, overlayContent.Add);
|
||||
|
||||
loadComponentSingleFile(dialogOverlay = new DialogOverlay
|
||||
{
|
||||
Depth = -7,
|
||||
}, overlayContent.Add);
|
||||
|
||||
loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener
|
||||
{
|
||||
Depth = -8,
|
||||
}, overlayContent.Add);
|
||||
|
||||
dependencies.Cache(idleTracker);
|
||||
dependencies.Cache(settings);
|
||||
dependencies.Cache(onscreenDisplay);
|
||||
@ -417,6 +435,7 @@ namespace osu.Game
|
||||
dependencies.Cache(beatmapSetOverlay);
|
||||
dependencies.Cache(notifications);
|
||||
dependencies.Cache(dialogOverlay);
|
||||
dependencies.Cache(accountCreation);
|
||||
|
||||
chatOverlay.StateChanged += state => channelManager.HighPollRate.Value = state == Visibility.Visible;
|
||||
|
||||
|
@ -60,6 +60,8 @@ namespace osu.Game
|
||||
|
||||
protected RulesetConfigCache RulesetConfigCache;
|
||||
|
||||
protected APIAccess API;
|
||||
|
||||
protected MenuCursorContainer MenuCursorContainer;
|
||||
|
||||
private Container content;
|
||||
@ -146,14 +148,14 @@ namespace osu.Game
|
||||
dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio));
|
||||
dependencies.CacheAs<ISkinSource>(SkinManager);
|
||||
|
||||
var api = new APIAccess(LocalConfig);
|
||||
API = new APIAccess(LocalConfig);
|
||||
|
||||
dependencies.Cache(api);
|
||||
dependencies.CacheAs<IAPIProvider>(api);
|
||||
dependencies.Cache(API);
|
||||
dependencies.CacheAs<IAPIProvider>(API);
|
||||
|
||||
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory));
|
||||
dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage));
|
||||
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, api, Audio, Host));
|
||||
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host));
|
||||
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, BeatmapManager, Host.Storage, contextFactory, Host));
|
||||
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
|
||||
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));
|
||||
@ -177,7 +179,7 @@ namespace osu.Game
|
||||
|
||||
FileStore.Cleanup();
|
||||
|
||||
AddInternal(api);
|
||||
AddInternal(API);
|
||||
|
||||
GlobalActionContainer globalBinding;
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public class AccountCreationBackground : Sprite
|
||||
{
|
||||
public AccountCreationBackground()
|
||||
{
|
||||
FillMode = FillMode.Fill;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Anchor = Anchor.CentreRight;
|
||||
Origin = Anchor.CentreRight;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LargeTextureStore textures)
|
||||
{
|
||||
Texture = textures.Get("Backgrounds/registration");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
const float x_movement = 80;
|
||||
|
||||
const float initial_move_time = 5000;
|
||||
const float loop_move_time = 10000;
|
||||
|
||||
base.LoadComplete();
|
||||
this.FadeInFromZero(initial_move_time / 4, Easing.OutQuint);
|
||||
this.MoveToX(x_movement / 2).MoveToX(0, initial_move_time, Easing.OutQuint);
|
||||
|
||||
using (BeginDelayedSequence(initial_move_time))
|
||||
{
|
||||
this
|
||||
.MoveToX(x_movement, loop_move_time, Easing.InOutSine)
|
||||
.Then().MoveToX(0, loop_move_time, Easing.InOutSine)
|
||||
.Loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs
Normal file
29
osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public abstract class AccountCreationScreen : Screen
|
||||
{
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
Content.FadeOut().Delay(200).FadeIn(200);
|
||||
}
|
||||
|
||||
protected override void OnResuming(Screen last)
|
||||
{
|
||||
base.OnResuming(last);
|
||||
Content.FadeIn(200);
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
{
|
||||
base.OnSuspending(next);
|
||||
Content.FadeOut(200);
|
||||
}
|
||||
}
|
||||
}
|
35
osu.Game/Overlays/AccountCreation/ErrorTextFlowContainer.cs
Normal file
35
osu.Game/Overlays/AccountCreation/ErrorTextFlowContainer.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public class ErrorTextFlowContainer : OsuTextFlowContainer
|
||||
{
|
||||
private readonly List<Drawable> errorDrawables = new List<Drawable>();
|
||||
|
||||
public ErrorTextFlowContainer()
|
||||
: base(cp => { cp.TextSize = 12; })
|
||||
{
|
||||
}
|
||||
|
||||
public void ClearErrors()
|
||||
{
|
||||
errorDrawables.ForEach(d => d.Expire());
|
||||
}
|
||||
|
||||
public void AddErrors(string[] errors)
|
||||
{
|
||||
ClearErrors();
|
||||
|
||||
if (errors == null) return;
|
||||
|
||||
foreach (var error in errors)
|
||||
errorDrawables.AddRange(AddParagraph(error, cp => cp.Colour = Color4.Red));
|
||||
}
|
||||
}
|
||||
}
|
220
osu.Game/Overlays/AccountCreation/ScreenEntry.cs
Normal file
220
osu.Game/Overlays/AccountCreation/ScreenEntry.cs
Normal file
@ -0,0 +1,220 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public class ScreenEntry : AccountCreationScreen
|
||||
{
|
||||
private ErrorTextFlowContainer usernameDescription;
|
||||
private ErrorTextFlowContainer emailAddressDescription;
|
||||
private ErrorTextFlowContainer passwordDescription;
|
||||
|
||||
private OsuTextBox usernameTextBox;
|
||||
private OsuTextBox emailTextBox;
|
||||
private OsuPasswordTextBox passwordTextBox;
|
||||
|
||||
private APIAccess api;
|
||||
private ShakeContainer registerShake;
|
||||
private IEnumerable<Drawable> characterCheckText;
|
||||
|
||||
private OsuTextBox[] textboxes;
|
||||
private ProcessingOverlay processingOverlay;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding(20),
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 20,
|
||||
Margin = new MarginPadding { Vertical = 10 },
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "Let's create an account!",
|
||||
},
|
||||
usernameTextBox = new OsuTextBox
|
||||
{
|
||||
PlaceholderText = "username",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
TabbableContentContainer = this
|
||||
},
|
||||
usernameDescription = new ErrorTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
},
|
||||
emailTextBox = new OsuTextBox
|
||||
{
|
||||
PlaceholderText = "email address",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
TabbableContentContainer = this
|
||||
},
|
||||
emailAddressDescription = new ErrorTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
},
|
||||
passwordTextBox = new OsuPasswordTextBox
|
||||
{
|
||||
PlaceholderText = "password",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
TabbableContentContainer = this,
|
||||
},
|
||||
passwordDescription = new ErrorTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
registerShake = new ShakeContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = new SettingsButton
|
||||
{
|
||||
Text = "Register",
|
||||
Margin = new MarginPadding { Vertical = 20 },
|
||||
Action = performRegistration
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
processingOverlay = new ProcessingOverlay { Alpha = 0 }
|
||||
};
|
||||
|
||||
textboxes = new[] { usernameTextBox, emailTextBox, passwordTextBox };
|
||||
|
||||
usernameDescription.AddText("This will be your public presence. No profanity, no impersonation. Avoid exposing your own personal details, too!");
|
||||
|
||||
emailAddressDescription.AddText("Will be used for notifications, account verification and in the case you forget your password. No spam, ever.");
|
||||
emailAddressDescription.AddText(" Make sure to get it right!", cp => cp.Font = "Exo2.0-Bold");
|
||||
|
||||
passwordDescription.AddText("At least ");
|
||||
characterCheckText = passwordDescription.AddText("8 characters long");
|
||||
passwordDescription.AddText(". Choose something long but also something you will remember, like a line from your favourite song.");
|
||||
|
||||
passwordTextBox.Current.ValueChanged += text => { characterCheckText.ForEach(s => s.Colour = text.Length == 0 ? Color4.White : Interpolation.ValueAt(text.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In)); };
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (!textboxes.Any(t => t.HasFocus))
|
||||
focusNextTextbox();
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
processingOverlay.Hide();
|
||||
}
|
||||
|
||||
private void performRegistration()
|
||||
{
|
||||
if (focusNextTextbox())
|
||||
{
|
||||
registerShake.Shake();
|
||||
return;
|
||||
}
|
||||
|
||||
usernameDescription.ClearErrors();
|
||||
emailAddressDescription.ClearErrors();
|
||||
passwordDescription.ClearErrors();
|
||||
|
||||
processingOverlay.Show();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
bool success;
|
||||
RegistrationRequest.RegistrationRequestErrors errors = null;
|
||||
|
||||
try
|
||||
{
|
||||
errors = api.CreateAccount(emailTextBox.Text, usernameTextBox.Text, passwordTextBox.Text);
|
||||
success = errors == null;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
if (errors != null)
|
||||
{
|
||||
usernameDescription.AddErrors(errors.User.Username);
|
||||
emailAddressDescription.AddErrors(errors.User.Email);
|
||||
passwordDescription.AddErrors(errors.User.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
passwordDescription.AddErrors(new[] { "Something happened... but we're not sure what." });
|
||||
}
|
||||
|
||||
registerShake.Shake();
|
||||
processingOverlay.Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
api.Login(emailTextBox.Text, passwordTextBox.Text);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private bool focusNextTextbox()
|
||||
{
|
||||
var nextTextbox = nextUnfilledTextbox();
|
||||
if (nextTextbox != null)
|
||||
{
|
||||
Schedule(() => GetContainingInputManager().ChangeFocus(nextTextbox));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private OsuTextBox nextUnfilledTextbox() => textboxes.FirstOrDefault(t => string.IsNullOrEmpty(t.Text));
|
||||
}
|
||||
}
|
133
osu.Game/Overlays/AccountCreation/ScreenWarning.cs
Normal file
133
osu.Game/Overlays/AccountCreation/ScreenWarning.cs
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public class ScreenWarning : AccountCreationScreen
|
||||
{
|
||||
private OsuTextFlowContainer multiAccountExplanationText;
|
||||
private LinkFlowContainer furtherAssistance;
|
||||
private APIAccess api;
|
||||
|
||||
private const string help_centre_url = "/help/wiki/Help_Centre#login";
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
if (string.IsNullOrEmpty(api.ProvidedUsername))
|
||||
{
|
||||
Content.FadeOut();
|
||||
Push(new ScreenEntry());
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnEntering(last);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colours, APIAccess api, OsuGame game, TextureStore textures)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
if (string.IsNullOrEmpty(api.ProvidedUsername))
|
||||
return;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Sprite
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Texture = textures.Get(@"Menu/dev-build-footer"),
|
||||
},
|
||||
new Sprite
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Texture = textures.Get(@"Menu/dev-build-footer"),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding(20),
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 150,
|
||||
Child = new OsuLogo
|
||||
{
|
||||
Scale = new Vector2(0.1f),
|
||||
Anchor = Anchor.Centre,
|
||||
Triangles = false,
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 28,
|
||||
Font = "Exo2.0-Light",
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = Color4.Red,
|
||||
Text = "Warning! 注意!",
|
||||
},
|
||||
multiAccountExplanationText = new OsuTextFlowContainer(cp => { cp.TextSize = 12; })
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
Text = "Help, I can't access my account!",
|
||||
Margin = new MarginPadding { Top = 50 },
|
||||
Action = () => game?.OpenUrlExternally(help_centre_url)
|
||||
},
|
||||
new DangerousSettingsButton
|
||||
{
|
||||
Text = "I understand. This account isn't for me.",
|
||||
Action = () => Push(new ScreenEntry())
|
||||
},
|
||||
furtherAssistance = new LinkFlowContainer(cp => { cp.TextSize = 12; })
|
||||
{
|
||||
Margin = new MarginPadding { Top = 20 },
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
multiAccountExplanationText.AddText("Are you ");
|
||||
multiAccountExplanationText.AddText(api.ProvidedUsername, cp => cp.Colour = colours.BlueLight);
|
||||
multiAccountExplanationText.AddText("? osu! has a policy of ");
|
||||
multiAccountExplanationText.AddText("one account per person!", cp => cp.Colour = colours.Yellow);
|
||||
multiAccountExplanationText.AddText(" Please be aware that creating more than one account per person may result in ");
|
||||
multiAccountExplanationText.AddText("permanent deactivation of accounts", cp => cp.Colour = colours.Yellow);
|
||||
multiAccountExplanationText.AddText(".");
|
||||
|
||||
furtherAssistance.AddText("Need further assistance? Contact us via our ");
|
||||
furtherAssistance.AddLink("support system", help_centre_url);
|
||||
furtherAssistance.AddText(".");
|
||||
}
|
||||
}
|
||||
}
|
65
osu.Game/Overlays/AccountCreation/ScreenWelcome.cs
Normal file
65
osu.Game/Overlays/AccountCreation/ScreenWelcome.cs
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Sprites;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.AccountCreation
|
||||
{
|
||||
public class ScreenWelcome : AccountCreationScreen
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding(20),
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 150,
|
||||
Child = new OsuLogo
|
||||
{
|
||||
Scale = new Vector2(0.1f),
|
||||
Anchor = Anchor.Centre,
|
||||
Triangles = false,
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 24,
|
||||
Font = "Exo2.0-Light",
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "New Player Registration",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 12,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "let's get you started",
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
Text = "Let's create an account!",
|
||||
Margin = new MarginPadding { Vertical = 120 },
|
||||
Action = () => Push(new ScreenWarning())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
110
osu.Game/Overlays/AccountCreationOverlay.cs
Normal file
110
osu.Game/Overlays/AccountCreationOverlay.cs
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.AccountCreation;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class AccountCreationOverlay : OsuFocusedOverlayContainer, IOnlineComponent
|
||||
{
|
||||
private const float transition_time = 400;
|
||||
|
||||
private ScreenWelcome welcomeScreen;
|
||||
|
||||
public AccountCreationOverlay()
|
||||
{
|
||||
Size = new Vector2(620, 450);
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, APIAccess api)
|
||||
{
|
||||
api.Register(this);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 5,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
},
|
||||
Masking = true,
|
||||
CornerRadius = 10,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.6f,
|
||||
},
|
||||
new DelayedLoadWrapper(new AccountCreationBackground(), 0),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.6f,
|
||||
AutoSizeDuration = transition_time,
|
||||
AutoSizeEasing = Easing.OutQuint,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.9f,
|
||||
},
|
||||
welcomeScreen = new ScreenWelcome(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
base.PopIn();
|
||||
this.FadeIn(transition_time, Easing.OutQuint);
|
||||
|
||||
if (welcomeScreen.ChildScreen != null)
|
||||
welcomeScreen.MakeCurrent();
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
base.PopOut();
|
||||
this.FadeOut(100);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case APIState.Offline:
|
||||
case APIState.Failing:
|
||||
break;
|
||||
case APIState.Connecting:
|
||||
break;
|
||||
case APIState.Online:
|
||||
State = Visibility.Hidden;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,11 +10,11 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
@ -12,12 +12,12 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
@ -1,72 +1,38 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatLine : Container
|
||||
public class ChatLine : CompositeDrawable
|
||||
{
|
||||
private static readonly Color4[] username_colours =
|
||||
{
|
||||
OsuColour.FromHex("588c7e"),
|
||||
OsuColour.FromHex("b2a367"),
|
||||
OsuColour.FromHex("c98f65"),
|
||||
OsuColour.FromHex("bc5151"),
|
||||
OsuColour.FromHex("5c8bd6"),
|
||||
OsuColour.FromHex("7f6ab7"),
|
||||
OsuColour.FromHex("a368ad"),
|
||||
OsuColour.FromHex("aa6880"),
|
||||
public const float LEFT_PADDING = default_message_padding + default_horizontal_padding * 2;
|
||||
|
||||
OsuColour.FromHex("6fad9b"),
|
||||
OsuColour.FromHex("f2e394"),
|
||||
OsuColour.FromHex("f2ae72"),
|
||||
OsuColour.FromHex("f98f8a"),
|
||||
OsuColour.FromHex("7daef4"),
|
||||
OsuColour.FromHex("a691f2"),
|
||||
OsuColour.FromHex("c894d3"),
|
||||
OsuColour.FromHex("d895b0"),
|
||||
private const float default_message_padding = 200;
|
||||
|
||||
OsuColour.FromHex("53c4a1"),
|
||||
OsuColour.FromHex("eace5c"),
|
||||
OsuColour.FromHex("ea8c47"),
|
||||
OsuColour.FromHex("fc4f4f"),
|
||||
OsuColour.FromHex("3d94ea"),
|
||||
OsuColour.FromHex("7760ea"),
|
||||
OsuColour.FromHex("af52c6"),
|
||||
OsuColour.FromHex("e25696"),
|
||||
protected virtual float MessagePadding => default_message_padding;
|
||||
|
||||
OsuColour.FromHex("677c66"),
|
||||
OsuColour.FromHex("9b8732"),
|
||||
OsuColour.FromHex("8c5129"),
|
||||
OsuColour.FromHex("8c3030"),
|
||||
OsuColour.FromHex("1f5d91"),
|
||||
OsuColour.FromHex("4335a5"),
|
||||
OsuColour.FromHex("812a96"),
|
||||
OsuColour.FromHex("992861"),
|
||||
};
|
||||
private const float default_horizontal_padding = 15;
|
||||
|
||||
public const float LEFT_PADDING = message_padding + padding * 2;
|
||||
protected virtual float HorizontalPadding => default_horizontal_padding;
|
||||
|
||||
private const float padding = 15;
|
||||
private const float message_padding = 200;
|
||||
private const float action_padding = 3;
|
||||
private const float text_size = 20;
|
||||
protected virtual float TextSize => 20;
|
||||
|
||||
private Color4 customUsernameColour;
|
||||
|
||||
@ -75,14 +41,13 @@ namespace osu.Game.Overlays.Chat
|
||||
public ChatLine(Message message)
|
||||
{
|
||||
Message = message;
|
||||
|
||||
Padding = new MarginPadding { Left = HorizontalPadding, Right = HorizontalPadding };
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Padding = new MarginPadding { Left = padding, Right = padding };
|
||||
}
|
||||
|
||||
private ChannelManager chatManager;
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ChannelManager chatManager { get; set; }
|
||||
|
||||
private Message message;
|
||||
private OsuSpriteText username;
|
||||
@ -106,10 +71,9 @@ namespace osu.Game.Overlays.Chat
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colours, ChannelManager chatManager)
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
this.chatManager = chatManager;
|
||||
customUsernameColour = colours.ChatBlue;
|
||||
}
|
||||
|
||||
@ -125,7 +89,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length],
|
||||
TextSize = text_size,
|
||||
TextSize = TextSize,
|
||||
};
|
||||
|
||||
if (hasBackground)
|
||||
@ -163,11 +127,11 @@ namespace osu.Game.Overlays.Chat
|
||||
};
|
||||
}
|
||||
|
||||
Children = new Drawable[]
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(message_padding, text_size),
|
||||
Size = new Vector2(MessagePadding, TextSize),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
timestamp = new OsuSpriteText
|
||||
@ -176,7 +140,7 @@ namespace osu.Game.Overlays.Chat
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = @"Exo2.0-SemiBold",
|
||||
FixedWidth = true,
|
||||
TextSize = text_size * 0.75f,
|
||||
TextSize = TextSize * 0.75f,
|
||||
},
|
||||
new MessageSender(message.Sender)
|
||||
{
|
||||
@ -191,7 +155,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = message_padding + padding },
|
||||
Padding = new MarginPadding { Left = MessagePadding + HorizontalPadding },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
contentFlow = new LinkFlowContainer(t =>
|
||||
@ -204,7 +168,7 @@ namespace osu.Game.Overlays.Chat
|
||||
t.Colour = OsuColour.FromHex(message.Sender.Colour);
|
||||
}
|
||||
|
||||
t.TextSize = text_size;
|
||||
t.TextSize = TextSize;
|
||||
})
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
@ -257,5 +221,44 @@ namespace osu.Game.Overlays.Chat
|
||||
new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction),
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly Color4[] username_colours =
|
||||
{
|
||||
OsuColour.FromHex("588c7e"),
|
||||
OsuColour.FromHex("b2a367"),
|
||||
OsuColour.FromHex("c98f65"),
|
||||
OsuColour.FromHex("bc5151"),
|
||||
OsuColour.FromHex("5c8bd6"),
|
||||
OsuColour.FromHex("7f6ab7"),
|
||||
OsuColour.FromHex("a368ad"),
|
||||
OsuColour.FromHex("aa6880"),
|
||||
|
||||
OsuColour.FromHex("6fad9b"),
|
||||
OsuColour.FromHex("f2e394"),
|
||||
OsuColour.FromHex("f2ae72"),
|
||||
OsuColour.FromHex("f98f8a"),
|
||||
OsuColour.FromHex("7daef4"),
|
||||
OsuColour.FromHex("a691f2"),
|
||||
OsuColour.FromHex("c894d3"),
|
||||
OsuColour.FromHex("d895b0"),
|
||||
|
||||
OsuColour.FromHex("53c4a1"),
|
||||
OsuColour.FromHex("eace5c"),
|
||||
OsuColour.FromHex("ea8c47"),
|
||||
OsuColour.FromHex("fc4f4f"),
|
||||
OsuColour.FromHex("3d94ea"),
|
||||
OsuColour.FromHex("7760ea"),
|
||||
OsuColour.FromHex("af52c6"),
|
||||
OsuColour.FromHex("e25696"),
|
||||
|
||||
OsuColour.FromHex("677c66"),
|
||||
OsuColour.FromHex("9b8732"),
|
||||
OsuColour.FromHex("8c5129"),
|
||||
OsuColour.FromHex("8c3030"),
|
||||
OsuColour.FromHex("1f5d91"),
|
||||
OsuColour.FromHex("4335a5"),
|
||||
OsuColour.FromHex("812a96"),
|
||||
OsuColour.FromHex("992861"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Chat
|
||||
public class DrawableChannel : Container
|
||||
{
|
||||
public readonly Channel Channel;
|
||||
private readonly ChatLineContainer flow;
|
||||
protected readonly ChatLineContainer ChatLineFlow;
|
||||
private readonly ScrollContainer scroll;
|
||||
|
||||
public DrawableChannel(Channel channel)
|
||||
@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = flow = new ChatLineContainer
|
||||
Child = ChatLineFlow = new ChatLineContainer
|
||||
{
|
||||
Padding = new MarginPadding { Left = 20, Right = 20 },
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -72,17 +72,19 @@ namespace osu.Game.Overlays.Chat
|
||||
Channel.PendingMessageResolved -= pendingMessageResolved;
|
||||
}
|
||||
|
||||
protected virtual ChatLine CreateChatLine(Message m) => new ChatLine(m);
|
||||
|
||||
private void newMessagesArrived(IEnumerable<Message> newMessages)
|
||||
{
|
||||
// Add up to last Channel.MAX_HISTORY messages
|
||||
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MaxHistory));
|
||||
|
||||
flow.AddRange(displayMessages.Select(m => new ChatLine(m)));
|
||||
ChatLineFlow.AddRange(displayMessages.Select(CreateChatLine));
|
||||
|
||||
if (scroll.IsScrolledToEnd(10) || !flow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
||||
if (scroll.IsScrolledToEnd(10) || !ChatLineFlow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
||||
scrollToEnd();
|
||||
|
||||
var staleMessages = flow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
||||
var staleMessages = ChatLineFlow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
||||
int count = staleMessages.Length - Channel.MaxHistory;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
@ -96,25 +98,25 @@ namespace osu.Game.Overlays.Chat
|
||||
|
||||
private void pendingMessageResolved(Message existing, Message updated)
|
||||
{
|
||||
var found = flow.Children.LastOrDefault(c => c.Message == existing);
|
||||
var found = ChatLineFlow.Children.LastOrDefault(c => c.Message == existing);
|
||||
if (found != null)
|
||||
{
|
||||
Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID.");
|
||||
|
||||
flow.Remove(found);
|
||||
ChatLineFlow.Remove(found);
|
||||
found.Message = updated;
|
||||
flow.Add(found);
|
||||
ChatLineFlow.Add(found);
|
||||
}
|
||||
}
|
||||
|
||||
private void messageRemoved(Message removed)
|
||||
{
|
||||
flow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
||||
ChatLineFlow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
||||
}
|
||||
|
||||
private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd());
|
||||
|
||||
private class ChatLineContainer : FillFlowContainer<ChatLine>
|
||||
protected class ChatLineContainer : FillFlowContainer<ChatLine>
|
||||
{
|
||||
protected override int Compare(Drawable x, Drawable y)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ namespace osu.Game.Overlays.Chat.Tabs
|
||||
Child = new DelayedLoadWrapper(new Avatar(value.Users.First())
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OpenOnClick = { Value = false },
|
||||
OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint),
|
||||
})
|
||||
{
|
||||
|
@ -6,8 +6,8 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
|
@ -10,7 +10,7 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||
{
|
||||
|
@ -79,7 +79,10 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
Margin = new MarginPadding { Bottom = 5 },
|
||||
Font = @"Exo2.0-Black",
|
||||
},
|
||||
form = new LoginForm()
|
||||
form = new LoginForm
|
||||
{
|
||||
RequestHide = RequestHide
|
||||
}
|
||||
};
|
||||
break;
|
||||
case APIState.Failing:
|
||||
@ -189,6 +192,8 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
private TextBox password;
|
||||
private APIAccess api;
|
||||
|
||||
public Action RequestHide;
|
||||
|
||||
private void performLogin()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(username.Text) && !string.IsNullOrEmpty(password.Text))
|
||||
@ -196,7 +201,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(APIAccess api, OsuConfigManager config)
|
||||
private void load(APIAccess api, OsuConfigManager config, AccountCreationOverlay accountCreation)
|
||||
{
|
||||
this.api = api;
|
||||
Direction = FillDirection.Vertical;
|
||||
@ -207,14 +212,14 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
{
|
||||
username = new OsuTextBox
|
||||
{
|
||||
PlaceholderText = "Email address",
|
||||
PlaceholderText = "email address",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = api?.ProvidedUsername ?? string.Empty,
|
||||
TabbableContentContainer = this
|
||||
},
|
||||
password = new OsuPasswordTextBox
|
||||
{
|
||||
PlaceholderText = "Password",
|
||||
PlaceholderText = "password",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
TabbableContentContainer = this,
|
||||
OnCommit = (sender, newText) => performLogin()
|
||||
@ -237,7 +242,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
new SettingsButton
|
||||
{
|
||||
Text = "Register",
|
||||
//Action = registerLink
|
||||
Action = () =>
|
||||
{
|
||||
RequestHide();
|
||||
accountCreation.Show();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -322,12 +331,10 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
public const float LABEL_LEFT_MARGIN = 20;
|
||||
|
||||
private readonly SpriteIcon statusIcon;
|
||||
|
||||
public Color4 StatusColour
|
||||
{
|
||||
set
|
||||
{
|
||||
statusIcon.FadeColour(value, 500, Easing.OutQuint);
|
||||
}
|
||||
set { statusIcon.FadeColour(value, 500, Easing.OutQuint); }
|
||||
}
|
||||
|
||||
public UserDropdownHeader()
|
||||
@ -368,10 +375,13 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
private enum UserAction
|
||||
{
|
||||
Online,
|
||||
|
||||
[Description(@"Do not disturb")]
|
||||
DoNotDisturb,
|
||||
|
||||
[Description(@"Appear offline")]
|
||||
AppearOffline,
|
||||
|
||||
[Description(@"Sign out")]
|
||||
SignOut,
|
||||
}
|
||||
|
@ -79,8 +79,6 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private readonly Container impactContainer;
|
||||
|
||||
private const float default_size = 480;
|
||||
|
||||
private const double early_activation = 60;
|
||||
|
||||
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
|
||||
@ -89,8 +87,6 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
EarlyActivationMilliseconds = early_activation;
|
||||
|
||||
Size = new Vector2(default_size);
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
@ -28,7 +28,6 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
|
||||
@ -288,7 +287,7 @@ namespace osu.Game.Screens.Play
|
||||
if (RulesetContainer.Replay == null)
|
||||
scoreManager.Import(score, true);
|
||||
|
||||
Push(new Results(score));
|
||||
Push(new SoloResults(score));
|
||||
|
||||
onCompletionEvent = null;
|
||||
});
|
||||
|
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Types;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class SoloResults : Results
|
||||
{
|
||||
public SoloResults(ScoreInfo score)
|
||||
: base(score)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
|
||||
{
|
||||
new ScoreOverviewPageInfo(Score, Beatmap),
|
||||
new BeatmapLeaderboardPageInfo(Score, Beatmap)
|
||||
};
|
||||
}
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public enum ResultMode
|
||||
public interface IResultPageInfo
|
||||
{
|
||||
Summary,
|
||||
Ranking,
|
||||
Share
|
||||
FontAwesome Icon { get; }
|
||||
|
||||
string Name { get; }
|
||||
|
||||
ResultsPage CreatePage();
|
||||
}
|
||||
}
|
@ -3,18 +3,19 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osuTK;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class ResultsPageRanking : ResultsPage
|
||||
public class RankingResultsPage : ResultsPage
|
||||
{
|
||||
public ResultsPageRanking(ScoreInfo score, WorkingBeatmap beatmap = null) : base(score, beatmap)
|
||||
public RankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap = null)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ namespace osu.Game.Screens.Ranking
|
||||
Colour = colours.GrayE,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new Leaderboard
|
||||
new BeatmapLeaderboard
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
@ -4,36 +4,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
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.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class ResultsPageScore : ResultsPage
|
||||
public class ScoreResultsPage : ResultsPage
|
||||
{
|
||||
private Container scoreContainer;
|
||||
private ScoreCounter scoreCounter;
|
||||
|
||||
public ResultsPageScore(ScoreInfo score, WorkingBeatmap beatmap) : base(score, beatmap) { }
|
||||
public ScoreResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
private FillFlowContainer<DrawableScoreStatistic> statisticsContainer;
|
||||
|
@ -5,6 +5,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
@ -13,27 +14,18 @@ using osu.Framework.Graphics.Shapes;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeButton : TabItem<ResultMode>
|
||||
public class ResultModeButton : TabItem<IResultPageInfo>, IHasTooltip
|
||||
{
|
||||
private readonly FontAwesome icon;
|
||||
private Color4 activeColour;
|
||||
private Color4 inactiveColour;
|
||||
private CircularContainer colouredPart;
|
||||
|
||||
public ResultModeButton(ResultMode mode) : base(mode)
|
||||
public ResultModeButton(IResultPageInfo mode)
|
||||
: base(mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case ResultMode.Summary:
|
||||
icon = FontAwesome.fa_asterisk;
|
||||
break;
|
||||
case ResultMode.Ranking:
|
||||
icon = FontAwesome.fa_list;
|
||||
break;
|
||||
case ResultMode.Share:
|
||||
icon = FontAwesome.fa_camera;
|
||||
break;
|
||||
}
|
||||
icon = mode.Icon;
|
||||
TooltipText = mode.Name;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -95,5 +87,7 @@ namespace osu.Game.Screens.Ranking
|
||||
protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, Easing.OutQuint);
|
||||
|
||||
protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint);
|
||||
|
||||
public string TooltipText { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeTabControl : TabControl<ResultMode>
|
||||
public class ResultModeTabControl : TabControl<IResultPageInfo>
|
||||
{
|
||||
public ResultModeTabControl()
|
||||
{
|
||||
@ -19,9 +19,9 @@ namespace osu.Game.Screens.Ranking
|
||||
TabContainer.Padding = new MarginPadding(5);
|
||||
}
|
||||
|
||||
protected override Dropdown<ResultMode> CreateDropdown() => null;
|
||||
protected override Dropdown<IResultPageInfo> CreateDropdown() => null;
|
||||
|
||||
protected override TabItem<ResultMode> CreateTabItem(ResultMode value) => new ResultModeButton(value)
|
||||
protected override TabItem<IResultPageInfo> CreateTabItem(IResultPageInfo value) => new ResultModeButton(value)
|
||||
{
|
||||
Anchor = TabContainer.Anchor,
|
||||
Origin = TabContainer.Origin
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
@ -21,9 +22,8 @@ using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class Results : OsuScreen
|
||||
public abstract class Results : OsuScreen
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private Container circleOuterBackground;
|
||||
private Container circleOuter;
|
||||
private Container circleInner;
|
||||
@ -34,6 +34,8 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
public override bool AllowBeatmapRulesetChange => false;
|
||||
|
||||
protected readonly ScoreInfo Score;
|
||||
|
||||
private Container currentPage;
|
||||
|
||||
private static readonly Vector2 background_blur = new Vector2(20);
|
||||
@ -44,9 +46,9 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
private const float circle_outer_scale = 0.96f;
|
||||
|
||||
public Results(ScoreInfo score)
|
||||
protected Results(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
Score = score;
|
||||
}
|
||||
|
||||
private const float transition_time = 800;
|
||||
@ -67,7 +69,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
backgroundParallax.FadeOut();
|
||||
modeChangeButtons.FadeOut();
|
||||
currentPage.FadeOut();
|
||||
currentPage?.FadeOut();
|
||||
|
||||
circleOuterBackground
|
||||
.FadeIn(transition_time, Easing.OutQuint)
|
||||
@ -90,7 +92,7 @@ namespace osu.Game.Screens.Ranking
|
||||
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
||||
{
|
||||
modeChangeButtons.FadeIn(transition_time, Easing.OutQuint);
|
||||
currentPage.FadeIn(transition_time, Easing.OutQuint);
|
||||
currentPage?.FadeIn(transition_time, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,7 +190,7 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = $"{score.MaxCombo}x",
|
||||
Text = $"{Score.MaxCombo}x",
|
||||
TextSize = 40,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Font = @"Exo2.0-Bold",
|
||||
@ -209,7 +211,7 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = $"{score.Accuracy:P2}",
|
||||
Text = $"{Score.Accuracy:P2}",
|
||||
TextSize = 40,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Font = @"Exo2.0-Bold",
|
||||
@ -262,30 +264,22 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
};
|
||||
|
||||
modeChangeButtons.AddItem(ResultMode.Summary);
|
||||
modeChangeButtons.AddItem(ResultMode.Ranking);
|
||||
//modeChangeButtons.AddItem(ResultMode.Share);
|
||||
foreach (var t in CreateResultPages())
|
||||
modeChangeButtons.AddItem(t);
|
||||
modeChangeButtons.Current.Value = modeChangeButtons.Items.FirstOrDefault();
|
||||
|
||||
modeChangeButtons.Current.ValueChanged += mode =>
|
||||
modeChangeButtons.Current.BindValueChanged(m =>
|
||||
{
|
||||
currentPage?.FadeOut();
|
||||
currentPage?.Expire();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ResultMode.Summary:
|
||||
currentPage = new ResultsPageScore(score, Beatmap.Value);
|
||||
break;
|
||||
case ResultMode.Ranking:
|
||||
currentPage = new ResultsPageRanking(score, Beatmap.Value);
|
||||
break;
|
||||
}
|
||||
currentPage = m?.CreatePage();
|
||||
|
||||
if (currentPage != null)
|
||||
circleInner.Add(currentPage);
|
||||
};
|
||||
|
||||
modeChangeButtons.Current.TriggerChange();
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<IResultPageInfo> CreateResultPages();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultsPage : Container
|
||||
public abstract class ResultsPage : Container
|
||||
{
|
||||
protected readonly ScoreInfo Score;
|
||||
protected readonly WorkingBeatmap Beatmap;
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
protected ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
Score = score;
|
||||
Beatmap = beatmap;
|
||||
|
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class BeatmapLeaderboardPageInfo : IResultPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public BeatmapLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public FontAwesome Icon => FontAwesome.fa_list;
|
||||
|
||||
public string Name => @"Beatmap Leaderboard";
|
||||
|
||||
public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap);
|
||||
}
|
||||
}
|
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class ScoreOverviewPageInfo : IResultPageInfo
|
||||
{
|
||||
public FontAwesome Icon => FontAwesome.fa_asterisk;
|
||||
|
||||
public string Name => "Overview";
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public ScoreOverviewPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public ResultsPage CreatePage()
|
||||
{
|
||||
return new ScoreResultsPage(score, beatmap);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public readonly BeatmapDetails Details;
|
||||
public readonly Leaderboard Leaderboard;
|
||||
public readonly BeatmapLeaderboard Leaderboard;
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
public WorkingBeatmap Beatmap
|
||||
@ -52,7 +52,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
default:
|
||||
Details.Hide();
|
||||
Leaderboard.Scope = (LeaderboardScope)tab - 1;
|
||||
Leaderboard.Scope = (BeatmapLeaderboardScope)tab - 1;
|
||||
Leaderboard.Show();
|
||||
break;
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Select
|
||||
Alpha = 0,
|
||||
Margin = new MarginPadding { Top = details_padding },
|
||||
},
|
||||
Leaderboard = new Leaderboard
|
||||
Leaderboard = new BeatmapLeaderboard
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
|
@ -24,12 +24,12 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
{
|
||||
base.Filter(criteria);
|
||||
|
||||
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps;
|
||||
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || (Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
|
||||
|
||||
if (!string.IsNullOrEmpty(criteria.SearchText))
|
||||
foreach (var criteriaTerm in criteria.SearchTerms)
|
||||
match &=
|
||||
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
|
||||
Beatmap.Version.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0;
|
||||
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
|
||||
Beatmap.Version.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0;
|
||||
|
||||
Filtered.Value = !match;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
|
||||
@ -10,8 +12,22 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
public GroupMode Group;
|
||||
public SortMode Sort;
|
||||
public string SearchText;
|
||||
|
||||
public string[] SearchTerms = Array.Empty<string>();
|
||||
|
||||
public RulesetInfo Ruleset;
|
||||
public bool AllowConvertedBeatmaps;
|
||||
|
||||
private string searchText;
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get { return searchText; }
|
||||
set
|
||||
{
|
||||
searchText = value;
|
||||
SearchTerms = searchText.Split(',', ' ', '!').Where(s => !string.IsNullOrEmpty(s)).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public class BeatmapLeaderboard : Leaderboard<BeatmapLeaderboardScope, ScoreInfo>
|
||||
{
|
||||
public Action<ScoreInfo> ScoreSelected;
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
if (beatmap == value)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
Scores = null;
|
||||
|
||||
UpdateScores();
|
||||
}
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private APIAccess api { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ruleset.ValueChanged += _ => UpdateScores();
|
||||
}
|
||||
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||
{
|
||||
if (Scope == BeatmapLeaderboardScope.Local)
|
||||
{
|
||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Beatmap?.OnlineBeatmapID == null)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.Unavailable;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Scope != BeatmapLeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||
{
|
||||
PlaceholderState = PlaceholderState.NotSupporter;
|
||||
return null;
|
||||
}
|
||||
|
||||
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||
|
||||
req.Success += r => scoresCallback?.Invoke(r.Scores);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override LeaderboardScore CreateDrawableScore(ScoreInfo model, int index) => new LeaderboardScore(model, index)
|
||||
{
|
||||
Action = () => ScoreSelected?.Invoke(model)
|
||||
};
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public enum LeaderboardScope
|
||||
public enum BeatmapLeaderboardScope
|
||||
{
|
||||
Local,
|
||||
Country,
|
@ -28,7 +28,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Options;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select
|
||||
});
|
||||
}
|
||||
|
||||
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new Results(s));
|
||||
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new SoloResults(s));
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
|
@ -8,7 +8,8 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeAccessorOwnerBody/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeModifiersOrder/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue"></s:String>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexRemoved">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeModifiers/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignedValueIsNeverUsed/@EntryIndexedValue">HINT</s:String>
|
||||
|
Loading…
Reference in New Issue
Block a user