1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:17:26 +08:00

Initial design for user registration dialog

This commit is contained in:
Dean Herbert 2018-12-04 20:33:29 +09:00
parent 21305ffd71
commit 1a974f64de
11 changed files with 384 additions and 20 deletions

View File

@ -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;
}

View File

@ -0,0 +1,19 @@
// 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.Containers;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual
{
public class TestCaseAccountCreationOverlay : OsuTestCase
{
public TestCaseAccountCreationOverlay()
{
var accountCreation = new AccountCreationOverlay();
Child = accountCreation;
accountCreation.State = Visibility.Visible;
}
}
}

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -189,6 +189,11 @@ namespace osu.Game.Online.API
this.password = password;
}
public void CreateAccount(string email, string username, string password)
{
Debug.Assert(State == APIState.Offline);
}
/// <summary>
/// Handle a single API request.
/// </summary>

View File

@ -0,0 +1,23 @@
// 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.IO.Network;
namespace osu.Game.Online.API
{
internal class RegsitrationRequest : JsonWebRequest<OAuthToken>
{
internal string Username;
internal string Email;
internal string Password;
protected override void PrePerform()
{
AddParameter("user", Username);
AddParameter("user_email", Email);
AddParameter("password", Password);
base.PrePerform();
}
}
}

View File

@ -61,6 +61,8 @@ namespace osu.Game
private DialogOverlay dialogOverlay;
private AccountCreationOverlay accountCreation;
private DirectOverlay direct;
private SocialOverlay social;
@ -405,6 +407,11 @@ namespace osu.Game
Depth = -6,
}, overlayContent.Add);
loadComponentSingleFile(accountCreation = new AccountCreationOverlay
{
Depth = -7,
}, overlayContent.Add);
dependencies.Cache(idleTracker);
dependencies.Cache(settings);
dependencies.Cache(onscreenDisplay);
@ -417,6 +424,7 @@ namespace osu.Game
dependencies.Cache(beatmapSetOverlay);
dependencies.Cache(notifications);
dependencies.Cache(dialogOverlay);
dependencies.Cache(accountCreation);
Add(externalLinkOpener = new ExternalLinkOpener());

View File

@ -0,0 +1,45 @@
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();
}
}
}
}

View File

@ -0,0 +1,234 @@
// 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.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Overlays.AccountCreation;
using osu.Game.Overlays.Settings;
using osuTK;
namespace osu.Game.Overlays
{
public class AccountCreationOverlay : OsuFocusedOverlayContainer, IOnlineComponent
{
private OsuTextFlowContainer usernameDescription;
private OsuTextFlowContainer emailAddressDescription;
private OsuTextFlowContainer passwordDescription;
private OsuTextBox usernameTextBox;
private OsuTextBox emailTextBox;
private OsuPasswordTextBox passwordTextBox;
private APIAccess api;
private ShakeContainer registerShake;
private IEnumerable<SpriteText> characterCheckText;
private const float transition_time = 400;
public AccountCreationOverlay()
{
Size = new Vector2(620, 450);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
State = Visibility.Visible;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api)
{
this.api = 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,
},
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 OsuTextFlowContainer(cp => { cp.TextSize = 12; })
{
RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y
},
emailTextBox = new OsuTextBox
{
PlaceholderText = "email address",
RelativeSizeAxes = Axes.X,
Text = api.ProvidedUsername ?? string.Empty,
TabbableContentContainer = this
},
emailAddressDescription = new OsuTextFlowContainer(cp => { cp.TextSize = 12; })
{
RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y
},
passwordTextBox = new OsuPasswordTextBox
{
PlaceholderText = "password",
RelativeSizeAxes = Axes.X,
TabbableContentContainer = this,
},
passwordDescription = new OsuTextFlowContainer(cp => { cp.TextSize = 12; })
{
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
}
}
}
},
}
},
}
}
}
}
};
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));
};
}
private void performRegistration()
{
var textbox = nextUnfilledTextbox();
if (textbox != null)
{
Schedule(() => GetContainingInputManager().ChangeFocus(textbox));
registerShake.Shake();
return;
}
api.CreateAccount(emailTextBox.Text, usernameTextBox.Text, passwordTextBox.Text);
}
private OsuTextBox nextUnfilledTextbox()
{
OsuTextBox textboxIfUsable(OsuTextBox textbox) => !string.IsNullOrEmpty(textbox.Text) ? null : textbox;
return textboxIfUsable(usernameTextBox) ?? textboxIfUsable(emailTextBox) ?? textboxIfUsable(passwordTextBox);
}
protected override void PopIn()
{
base.PopIn();
this.FadeIn(transition_time, Easing.OutQuint);
var nextTextbox = nextUnfilledTextbox();
if (nextTextbox != null)
Schedule(() => GetContainingInputManager().ChangeFocus(nextTextbox));
}
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:
break;
}
}
}
}

View File

@ -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,
}

View File

@ -24,4 +24,7 @@
<PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Overlays\Settings\AccountCreation" />
</ItemGroup>
</Project>