1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 20:22:55 +08:00

Merge pull request #558 from peppy/avatars-and-login

Avatar refactoring & better focus handling in login form.
This commit is contained in:
Dan Balasescu 2017-03-29 08:12:05 +09:00 committed by GitHub
commit 2bb8e3bae8
17 changed files with 263 additions and 255 deletions

@ -1 +1 @@
Subproject commit 51737ec1320b4ea9dce4978f24e1d77a28f0a98e Subproject commit 1ade9b9e6dc03cfad30f5d08865310babf67404f

View File

@ -33,12 +33,25 @@ namespace osu.Game.Beatmaps.Drawables
Children = new Drawable[] Children = new Drawable[]
{ {
new DelayedLoadContainer
{
RelativeSizeAxes = Axes.Both,
TimeBeforeLoad = 100,
Children = new[]
{
new PanelBackground(beatmap)
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
}
}
},
new FillFlowContainer new FillFlowContainer
{ {
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 }, Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 },
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new[] Children = new Drawable[]
{ {
title = new OsuSpriteText title = new OsuSpriteText
{ {
@ -71,23 +84,13 @@ namespace osu.Game.Beatmaps.Drawables
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuGameBase game) private void load(OsuConfigManager config)
{ {
this.config = config; this.config = config;
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode); preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
preferUnicode.ValueChanged += preferUnicode_changed; preferUnicode.ValueChanged += preferUnicode_changed;
preferUnicode_changed(preferUnicode, null); preferUnicode_changed(preferUnicode, null);
new PanelBackground(beatmap)
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
}.LoadAsync(game, b =>
{
Add(b);
b.FadeInFromZero(200);
});
} }
private void preferUnicode_changed(object sender, EventArgs e) private void preferUnicode_changed(object sender, EventArgs e)

View File

@ -12,6 +12,7 @@ using osu.Framework.Configuration;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Users;
namespace osu.Game.Online.API namespace osu.Game.Online.API
{ {
@ -118,7 +119,7 @@ namespace osu.Game.Online.API
//todo: this fails even on network-related issues. we should probably handle those differently. //todo: this fails even on network-related issues. we should probably handle those differently.
//NotificationManager.ShowMessage("Login failed!"); //NotificationManager.ShowMessage("Login failed!");
log.Add(@"Login failed!"); log.Add(@"Login failed!");
clearCredentials(); Password = null;
continue; continue;
} }

View File

@ -1,6 +1,8 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Users;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class GetUserRequest : APIRequest<User> public class GetUserRequest : APIRequest<User>

View File

@ -91,7 +91,7 @@ namespace osu.Game.Online.Chat.Drawables
new OsuSpriteText new OsuSpriteText
{ {
Font = @"Exo2.0-BoldItalic", Font = @"Exo2.0-BoldItalic",
Text = $@"{Message.User.Name}:", Text = $@"{Message.User.Username}:",
Colour = getUsernameColour(Message), Colour = getUsernameColour(Message),
TextSize = text_size, TextSize = text_size,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,

View File

@ -3,6 +3,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Users;
namespace osu.Game.Online.Chat namespace osu.Game.Online.Chat
{ {

View File

@ -1,19 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
namespace osu.Game.Online
{
public class User
{
[JsonProperty(@"username")]
public string Name;
[JsonProperty(@"id")]
public int Id;
[JsonProperty(@"colour")]
public string Colour;
}
}

View File

@ -67,6 +67,8 @@ namespace osu.Game.Overlays
optionsSection.Bounding = true; optionsSection.Bounding = true;
FadeIn(transition_time, EasingTypes.OutQuint); FadeIn(transition_time, EasingTypes.OutQuint);
optionsSection.TriggerFocus();
} }
protected override void PopOut() protected override void PopOut()

View File

@ -29,7 +29,7 @@ namespace osu.Game.Overlays
{ {
public class MusicController : FocusedOverlayContainer public class MusicController : FocusedOverlayContainer
{ {
private MusicControllerBackground backgroundSprite; private Drawable currentBackground;
private DragBar progress; private DragBar progress;
private TextAwesome playButton; private TextAwesome playButton;
private SpriteText title, artist; private SpriteText title, artist;
@ -44,7 +44,6 @@ namespace osu.Game.Overlays
private Bindable<bool> preferUnicode; private Bindable<bool> preferUnicode;
private WorkingBeatmap current; private WorkingBeatmap current;
private BeatmapDatabase beatmaps; private BeatmapDatabase beatmaps;
private Framework.Game game;
private Container dragContainer; private Container dragContainer;
@ -78,10 +77,8 @@ namespace osu.Game.Overlays
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuGameBase osuGame, OsuConfigManager config, BeatmapDatabase beatmaps, OsuColour colours) private void load(OsuGameBase game, OsuConfigManager config, BeatmapDatabase beatmaps, OsuColour colours)
{ {
game = osuGame;
unicodeString = config.GetUnicodeString; unicodeString = config.GetUnicodeString;
Children = new Drawable[] Children = new Drawable[]
@ -212,15 +209,15 @@ namespace osu.Game.Overlays
}; };
this.beatmaps = beatmaps; this.beatmaps = beatmaps;
trackManager = osuGame.Audio.Track; trackManager = game.Audio.Track;
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode); preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
preferUnicode.ValueChanged += preferUnicode_changed; preferUnicode.ValueChanged += preferUnicode_changed;
beatmapSource = osuGame.Beatmap ?? new Bindable<WorkingBeatmap>(); beatmapSource = game.Beatmap ?? new Bindable<WorkingBeatmap>();
playList = beatmaps.GetAllWithChildren<BeatmapSetInfo>(); playList = beatmaps.GetAllWithChildren<BeatmapSetInfo>();
backgroundSprite = new MusicControllerBackground(); currentBackground = new MusicControllerBackground();
dragContainer.Add(backgroundSprite); dragContainer.Add(currentBackground);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -351,29 +348,29 @@ namespace osu.Game.Overlays
} }
}); });
MusicControllerBackground newBackground; dragContainer.Add(new AsyncLoadContainer
{
(newBackground = new MusicControllerBackground(beatmap)).LoadAsync(game, delegate RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue,
Children = new[] { new MusicControllerBackground(beatmap) },
FinishedLoading = d =>
{ {
dragContainer.Add(newBackground);
switch (direction) switch (direction)
{ {
case TransformDirection.Next: case TransformDirection.Next:
newBackground.Position = new Vector2(400, 0); d.Position = new Vector2(400, 0);
newBackground.MoveToX(0, 500, EasingTypes.OutCubic); d.MoveToX(0, 500, EasingTypes.OutCubic);
backgroundSprite.MoveToX(-400, 500, EasingTypes.OutCubic); currentBackground.MoveToX(-400, 500, EasingTypes.OutCubic);
break; break;
case TransformDirection.Prev: case TransformDirection.Prev:
newBackground.Position = new Vector2(-400, 0); d.Position = new Vector2(-400, 0);
newBackground.MoveToX(0, 500, EasingTypes.OutCubic); d.MoveToX(0, 500, EasingTypes.OutCubic);
backgroundSprite.MoveToX(400, 500, EasingTypes.OutCubic); currentBackground.MoveToX(400, 500, EasingTypes.OutCubic);
break; break;
} }
currentBackground.Expire();
backgroundSprite.Expire(); currentBackground = d;
backgroundSprite = newBackground; }
}); });
}; };
} }
@ -422,8 +419,8 @@ namespace osu.Game.Overlays
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
CacheDrawnFrameBuffer = true; CacheDrawnFrameBuffer = true;
RelativeSizeAxes = Axes.Both;
Depth = float.MaxValue; Depth = float.MaxValue;
RelativeSizeAxes = Axes.Both;
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -11,12 +11,14 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using OpenTK; using OpenTK;
using osu.Framework.Input;
namespace osu.Game.Overlays.Options.Sections.General namespace osu.Game.Overlays.Options.Sections.General
{ {
public class LoginOptions : OptionsSubsection, IOnlineComponent public class LoginOptions : OptionsSubsection, IOnlineComponent
{ {
private bool bounding = true; private bool bounding = true;
private LoginForm form;
protected override string Header => "Account"; protected override string Header => "Account";
@ -40,12 +42,14 @@ namespace osu.Game.Overlays.Options.Sections.General
public void APIStateChanged(APIAccess api, APIState state) public void APIStateChanged(APIAccess api, APIState state)
{ {
form = null;
switch (state) switch (state)
{ {
case APIState.Offline: case APIState.Offline:
Children = new Drawable[] Children = new Drawable[]
{ {
new LoginForm() form = new LoginForm()
}; };
break; break;
case APIState.Failing: case APIState.Failing:
@ -82,6 +86,14 @@ namespace osu.Game.Overlays.Options.Sections.General
}; };
break; break;
} }
form?.TriggerFocus();
}
protected override bool OnFocus(InputState state)
{
form?.TriggerFocus();
return base.OnFocus(state);
} }
private class LoginForm : FillFlowContainer private class LoginForm : FillFlowContainer
@ -144,6 +156,19 @@ namespace osu.Game.Overlays.Options.Sections.General
} }
}; };
} }
protected override bool OnFocus(InputState state)
{
Schedule(() =>
{
if (string.IsNullOrEmpty(username.Text))
username.TriggerFocus();
else
password.TriggerFocus();
});
return base.OnFocus(state);
}
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Toolbar
{ {
internal class ToolbarUserButton : ToolbarButton, IOnlineComponent internal class ToolbarUserButton : ToolbarButton, IOnlineComponent
{ {
private readonly Avatar avatar; private readonly UpdateableAvatar avatar;
public ToolbarUserButton() public ToolbarUserButton()
{ {
@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Toolbar
Add(new OpaqueBackground { Depth = 1 }); Add(new OpaqueBackground { Depth = 1 });
Flow.Add(avatar = new Avatar Flow.Add(avatar = new UpdateableAvatar
{ {
Masking = true, Masking = true,
Size = new Vector2(32), Size = new Vector2(32),
@ -52,11 +52,11 @@ namespace osu.Game.Overlays.Toolbar
{ {
default: default:
Text = @"Guest"; Text = @"Guest";
avatar.UserId = 1; avatar.User = new User();
break; break;
case APIState.Online: case APIState.Online:
Text = api.Username; Text = api.Username;
avatar.UserId = api.LocalUser.Value.Id; avatar.User = api.LocalUser;
break; break;
} }
} }

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Colour;
@ -30,9 +29,7 @@ namespace osu.Game.Screens.Select
{ {
private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0); private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0);
private BufferedContainer beatmapInfoContainer; private Drawable beatmapInfoContainer;
private OsuGameBase game;
public BeatmapInfoWedge() public BeatmapInfoWedge()
{ {
@ -49,12 +46,6 @@ namespace osu.Game.Screens.Select
}; };
} }
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
this.game = game;
}
protected override bool HideOnEscape => false; protected override bool HideOnEscape => false;
protected override void PopIn() protected override void PopIn()
@ -113,9 +104,21 @@ namespace osu.Game.Screens.Select
labels.AddRange(Ruleset.GetRuleset(beatmap.BeatmapInfo.Mode).GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); labels.AddRange(Ruleset.GetRuleset(beatmap.BeatmapInfo.Mode).GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s)));
} }
(beatmapInfoContainer = new BufferedContainer Add(beatmapInfoContainer = new AsyncLoadContainer
{ {
FinishedLoading = d =>
{
FadeIn(250);
lastContainer?.FadeOut(250);
lastContainer?.Expire();
},
Depth = newDepth, Depth = newDepth,
RelativeSizeAxes = Axes.Both,
Children = new[]
{
new BufferedContainer
{
PixelSnapping = true, PixelSnapping = true,
CacheDrawnFrameBuffer = true, CacheDrawnFrameBuffer = true,
Shear = -Shear, Shear = -Shear,
@ -204,14 +207,8 @@ namespace osu.Game.Screens.Select
} }
}, },
} }
}).LoadAsync(game, delegate (Drawable d) }
{ }
FadeIn(250);
lastContainer?.FadeOut(250);
lastContainer?.Expire();
Add(d);
}); });
} }

View File

@ -142,9 +142,16 @@ namespace osu.Game.Screens.Select.Leaderboards
Padding = new MarginPadding(edge_margin), Padding = new MarginPadding(edge_margin),
Children = new Drawable[] Children = new Drawable[]
{ {
avatar = new Avatar avatar = new DelayedLoadContainer
{ {
TimeBeforeLoad = 500,
FinishedLoading = d => d.FadeInFromZero(200),
Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2), Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2),
Children = new Drawable[]
{
new Avatar(Score.User ?? new User { Id = Score.UserID })
{
RelativeSizeAxes = Axes.Both,
CornerRadius = corner_radius, CornerRadius = corner_radius,
Masking = true, Masking = true,
EdgeEffect = new EdgeEffect EdgeEffect = new EdgeEffect
@ -153,7 +160,8 @@ namespace osu.Game.Screens.Select.Leaderboards
Radius = 1, Radius = 1,
Colour = Color4.Black.Opacity(0.2f), Colour = Color4.Black.Opacity(0.2f),
}, },
UserId = Score.User?.Id ?? Score.UserID, },
}
}, },
new Container new Container
{ {

View File

@ -1,8 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Diagnostics;
using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -13,102 +11,31 @@ namespace osu.Game.Users
{ {
public class Avatar : Container public class Avatar : Container
{ {
public Drawable Sprite; private readonly User user;
private long userId; /// <summary>
private OsuGameBase game; /// An avatar for specified user.
private Texture guestTexture; /// </summary>
/// <param name="user">The user. A null value will get a placeholder avatar.</param>
[BackgroundDependencyLoader(permitNulls: true)] public Avatar(User user = null)
private void load(OsuGameBase game, TextureStore textures)
{ {
this.game = game; this.user = user;
guestTexture = textures.Get(@"Online/avatar-guest");
}
public long UserId
{
get { return userId; }
set
{
if (userId == value)
return;
userId = value;
invalidateSprite();
}
}
private Task loadTask;
private void invalidateSprite()
{
Sprite?.FadeOut(100);
Sprite?.Expire();
Sprite = null;
}
private void updateSprite()
{
if (loadTask != null || Sprite != null) return;
var newSprite = userId > 1 ? new OnlineSprite($@"https://a.ppy.sh/{userId}", guestTexture) : new Sprite { Texture = guestTexture };
newSprite.FillMode = FillMode.Fill;
loadTask = newSprite.LoadAsync(game, s =>
{
Sprite = s;
Add(Sprite);
Sprite.FadeInFromZero(200);
loadTask = null;
});
}
private double timeVisible;
private bool shouldUpdate => Sprite != null || timeVisible > 500;
protected override void Update()
{
base.Update();
if (!shouldUpdate)
{
//Special optimisation to not start loading until we are within bounds of our closest ScrollContainer parent.
ScrollContainer scroll = null;
IContainer cursor = this;
while (scroll == null && (cursor = cursor.Parent) != null)
scroll = cursor as ScrollContainer;
if (scroll?.ScreenSpaceDrawQuad.Intersects(ScreenSpaceDrawQuad) ?? true)
timeVisible += Time.Elapsed;
else
timeVisible = 0;
}
if (shouldUpdate)
updateSprite();
}
public class OnlineSprite : Sprite
{
private readonly string url;
private readonly Texture fallbackTexture;
public OnlineSprite(string url, Texture fallbackTexture = null)
{
Debug.Assert(url != null);
this.url = url;
this.fallbackTexture = fallbackTexture;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
Texture = textures.Get(url) ?? fallbackTexture; Texture texture = null;
} if (user?.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}");
if (texture == null) texture = textures.Get(@"Online/avatar-guest");
Add(new Sprite
{
Texture = texture,
FillMode = FillMode.Fit,
Anchor = Anchor.Centre,
Origin = Anchor.Centre
});
} }
} }
} }

View File

@ -0,0 +1,54 @@
// Copyright (c) 2007-2017 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.Graphics.Containers;
namespace osu.Game.Users
{
/// <summary>
/// An avatar which can update to a new user when needed.
/// </summary>
public class UpdateableAvatar : Container
{
private Container displayedAvatar;
private User user;
public User User
{
get { return user; }
set
{
if (user?.Id == value?.Id)
return;
user = value;
if (IsLoaded)
updateAvatar();
}
}
protected override void LoadComplete()
{
base.LoadComplete();
updateAvatar();
}
private void updateAvatar()
{
displayedAvatar?.FadeOut(300);
displayedAvatar?.Expire();
Add(displayedAvatar = new AsyncLoadContainer
{
RelativeSizeAxes = Axes.Both,
FinishedLoading = d => d.FadeInFromZero(200),
Children = new[]
{
new Avatar(user) { RelativeSizeAxes = Axes.Both }
}
});
}
}
}

View File

@ -1,13 +1,23 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
namespace osu.Game.Users namespace osu.Game.Users
{ {
public class User public class User
{ {
public int Id; [JsonProperty(@"id")]
public long Id = 1;
[JsonProperty(@"username")]
public string Username; public string Username;
public Country Country; public Country Country;
public Team Team; public Team Team;
[JsonProperty(@"colour")]
public string Colour;
} }
} }

View File

@ -247,7 +247,6 @@
<Compile Include="Online\Chat\Drawables\DrawableChannel.cs" /> <Compile Include="Online\Chat\Drawables\DrawableChannel.cs" />
<Compile Include="Online\Chat\Drawables\ChatLine.cs" /> <Compile Include="Online\Chat\Drawables\ChatLine.cs" />
<Compile Include="Online\Chat\Message.cs" /> <Compile Include="Online\Chat\Message.cs" />
<Compile Include="Online\User.cs" />
<Compile Include="OsuGame.cs" /> <Compile Include="OsuGame.cs" />
<Compile Include="OsuGameBase.cs" /> <Compile Include="OsuGameBase.cs" />
<Compile Include="Overlays\ChatOverlay.cs" /> <Compile Include="Overlays\ChatOverlay.cs" />
@ -267,6 +266,7 @@
<Compile Include="Screens\Tournament\Teams\ITeamList.cs" /> <Compile Include="Screens\Tournament\Teams\ITeamList.cs" />
<Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" /> <Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" />
<Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" /> <Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" />
<Compile Include="Users\UpdateableAvatar.cs" />
<Compile Include="Users\User.cs" /> <Compile Include="Users\User.cs" />
<Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" /> <Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" />
<Compile Include="Database\BeatmapDatabase.cs" /> <Compile Include="Database\BeatmapDatabase.cs" />