1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-12 19:27:24 +08:00

Add Test Case, improve displaying the avatar, use a chatTabControl instead of putting both in ChatOverlay, readd shadow.

Requires osu-framework for a fix
This commit is contained in:
miterosan 2018-04-11 18:23:09 +02:00
parent 85f736ae89
commit 39ecc3d31d
8 changed files with 263 additions and 55 deletions

View File

@ -0,0 +1,96 @@

using System;
using System.Collections.Generic;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Online.Chat;
using osu.Game.Overlays.Chat;
using osu.Game.Users;
using OpenTK.Graphics;
namespace osu.Game.Tests.Visual
{
public class TestCaseChatTabControl : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ChatTabControl),
typeof(ChannelTabControl),
typeof(UserTabControl),
};
private readonly ChatTabControl chatTabControl;
private readonly SpriteText currentText;
public TestCaseChatTabControl()
{
Add(new Container
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Children = new Drawable[]
{
chatTabControl = new ChatTabControl
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Height = 50
},
new Box
{
Colour = Color4.Black.Opacity(0.1f),
RelativeSizeAxes = Axes.X,
Height = 50,
Depth = -1,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
}
}
});
Add(new Container()
{
Origin = Anchor.TopLeft,
Anchor = Anchor.TopLeft,
Children = new Drawable[]
{
currentText = new SpriteText
{
Text = "Currently selected chat: "
}
}
});
chatTabControl.OnRequestLeave += chat => chatTabControl.RemoveItem(chat);
chatTabControl.Current.ValueChanged += chat => currentText.Text = "Currently selected chat: " + chat.ToString();
AddStep("Add random user", () => addUser(RNG.Next(100000), RNG.Next().ToString()));
AddRepeatStep("3 random users", () => addUser(RNG.Next(100000), RNG.Next().ToString()), 3);
AddStep("Add random channel", () => addChannel(RNG.Next().ToString()));
}
private void addUser(long id, string name)
{
chatTabControl.AddItem(new UserChat(new User
{
Id = id,
Username = name
}));
}
private void addChannel(string name)
{
this.chatTabControl.AddItem(new ChannelChat
{
Name = name
});
}
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Online.API; using osu.Game.Online.API;
@ -18,7 +19,7 @@ namespace osu.Game.Online.Chat
/// <summary> /// <summary>
/// Manages everything chat related /// Manages everything chat related
/// </summary> /// </summary>
public class ChatManager : IOnlineComponent public class ChatManager : Component, IOnlineComponent
{ {
/// <summary> /// <summary>
/// The channels the player joins on startup /// The channels the player joins on startup
@ -217,7 +218,7 @@ namespace osu.Game.Online.Chat
foreach (var withoutReplyGroup in withoutReplyGroups) foreach (var withoutReplyGroup in withoutReplyGroups)
{ {
var chat = new UserChat(new User {Id = withoutReplyGroup.First().TargetId }); var chat = new UserChat(new User { Id = withoutReplyGroup.First().TargetId });
chat.AddNewMessages(withoutReplyGroup.ToArray()); chat.AddNewMessages(withoutReplyGroup.ToArray());
OpenedUserChats.Add(chat); OpenedUserChats.Add(chat);

View File

@ -38,5 +38,7 @@ namespace osu.Game.Online.Chat
req.Failure += exception => Logger.Error(exception, $"Requesting details for user with Id:{User.Id} failed."); req.Failure += exception => Logger.Error(exception, $"Requesting details for user with Id:{User.Id} failed.");
api.Queue(req); api.Queue(req);
} }
public override string ToString() => User.Username ?? User.Id.ToString();
} }
} }

View File

@ -0,0 +1,99 @@
using System;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Online.Chat;
namespace osu.Game.Overlays.Chat
{
public class ChatTabControl : Container, IHasCurrentValue<ChatBase>
{
public readonly ChannelTabControl channelTabControl;
private readonly UserTabControl userTabControl;
public Bindable<ChatBase> Current { get; } = new Bindable<ChatBase>();
public Action<ChatBase> OnRequestLeave;
public Action OnRequestChannelSelection;
public ChatTabControl()
{
Masking = false;
Children = new Drawable[]
{
channelTabControl = new ChannelTabControl
{
Width = 0.5f,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
OnRequestLeave = chat => OnRequestLeave?.Invoke(chat)
},
userTabControl = new UserTabControl
{
Width = 0.5f,
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
RelativeSizeAxes = Axes.Both,
OnRequestLeave = chat => OnRequestLeave?.Invoke(chat)
},
};
Current.ValueChanged += currentTabChanged;
channelTabControl.Current.ValueChanged += chat =>
{
if (chat != null)
Current.Value = chat;
};
userTabControl.Current.ValueChanged += chat =>
{
if (chat != null)
Current.Value = chat;
};
}
private void currentTabChanged(ChatBase tab)
{
switch (tab)
{
case UserChat userChat:
userTabControl.Current.Value = userChat;
channelTabControl.Current.Value = null;
break;
case ChannelChat channelChat:
channelTabControl.Current.Value = channelChat;
userTabControl.Current.Value = null;
break;
}
}
public void AddItem(ChatBase chat)
{
switch (chat)
{
case UserChat userChat:
userTabControl.AddItem(userChat);
break;
case ChannelChat channelChat:
channelTabControl.AddItem(channelChat);
break;
}
}
public void RemoveItem(ChatBase chat)
{
switch (chat)
{
case UserChat userChat:
userTabControl.RemoveItem(userChat);
Current.Value = null;
break;
case ChannelChat channelChat:
channelTabControl.RemoveItem(channelChat);
Current.Value = null;
break;
}
}
}
}

View File

@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Chat
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
newMessagesArrived(Chat.Messages); Scheduler.Add(() => newMessagesArrived(Chat.Messages));
} }
protected override void LoadComplete() protected override void LoadComplete()

View File

@ -2,6 +2,7 @@
// 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; using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Chat; using osu.Game.Online.Chat;
@ -9,16 +10,22 @@ using OpenTK;
namespace osu.Game.Overlays.Chat namespace osu.Game.Overlays.Chat
{ {
public class UserChatTabControl : OsuTabControl<UserChat> public class UserTabControl : OsuTabControl<UserChat>
{ {
protected override TabItem<UserChat> CreateTabItem(UserChat value) => new UserChatTabItem(value) { OnRequestClose = tabCloseRequested }; protected override TabItem<UserChat> CreateTabItem(UserChat value) => new UserTabItem(value) { OnRequestClose = tabCloseRequested };
protected override Dropdown<UserChat> CreateDropdown() => null;
public Action<UserChat> OnRequestLeave; public Action<UserChat> OnRequestLeave;
public UserChatTabControl() public UserTabControl()
{ {
TabContainer.Spacing = new Vector2(-10, 0); TabContainer.Spacing = new Vector2(-10, 0);
TabContainer.Masking = false; TabContainer.Masking = false;
Margin = new MarginPadding
{
Right = 10
};
} }
protected override void AddTabItem(TabItem<UserChat> item, bool addToDropdown = true) protected override void AddTabItem(TabItem<UserChat> item, bool addToDropdown = true)
@ -46,6 +53,7 @@ namespace osu.Game.Overlays.Chat
if (SelectedTab != null) if (SelectedTab != null)
SelectedTab.Active.Value = false; SelectedTab.Active.Value = false;
SelectedTab = null; SelectedTab = null;
} }
} }
} }

View File

@ -19,7 +19,7 @@ using OpenTK.Graphics;
namespace osu.Game.Overlays.Chat namespace osu.Game.Overlays.Chat
{ {
public class UserChatTabItem : TabItem<UserChat> public class UserTabItem : TabItem<UserChat>
{ {
private static readonly Vector2 shear = new Vector2(1f / 5f, 0); private static readonly Vector2 shear = new Vector2(1f / 5f, 0);
private readonly UserChat chat; private readonly UserChat chat;
@ -29,18 +29,19 @@ namespace osu.Game.Overlays.Chat
private readonly Container backgroundContainer; private readonly Container backgroundContainer;
private readonly Box backgroundBox; private readonly Box backgroundBox;
private readonly OsuSpriteText username; private readonly OsuSpriteText username;
private readonly Avatar avatarContainer;
private readonly ChatTabItemCloseButton closeButton; private readonly ChatTabItemCloseButton closeButton;
public UserChatTabItem(UserChat value) public UserTabItem(UserChat value)
: base(value) : base(value)
{ {
chat = value; chat = value;
AutoSizeAxes = Axes.X; AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y; Height = 50;
Origin = Anchor.BottomRight; Origin = Anchor.BottomRight;
Anchor = Anchor.BottomRight; Anchor = Anchor.BottomRight;
EdgeEffect = deactivateEdgeEffect; EdgeEffect = activateEdgeEffect;
Masking = false; Masking = true;
Shear = shear; Shear = shear;
Children = new Drawable[] Children = new Drawable[]
{ {
@ -116,7 +117,11 @@ namespace osu.Game.Overlays.Chat
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Masking = true, Masking = true,
Child = new Avatar(value.User) Child = new DelayedLoadWrapper(new Avatar(value.User)
{
Size = new Vector2(ChatOverlay.TAB_AREA_HEIGHT),
OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint),
})
{ {
Size = new Vector2(ChatOverlay.TAB_AREA_HEIGHT), Size = new Vector2(ChatOverlay.TAB_AREA_HEIGHT),
} }
@ -136,6 +141,10 @@ namespace osu.Game.Overlays.Chat
Height = 1, Height = 1,
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Margin = new MarginPadding
{
Right = 5
},
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Action = delegate Action = delegate
{ {
@ -148,13 +157,13 @@ namespace osu.Game.Overlays.Chat
}; };
} }
public Action<UserChatTabItem> OnRequestClose; public Action<UserTabItem> OnRequestClose;
private readonly EdgeEffectParameters activateEdgeEffect = new EdgeEffectParameters private readonly EdgeEffectParameters activateEdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Shadow, Type = EdgeEffectType.Shadow,
Radius = 30, Radius = 15,
Colour = Color4.Black.Opacity(0.3f), Colour = Color4.Black.Opacity(0.4f),
}; };
protected override void OnActivated() protected override void OnActivated()
@ -168,7 +177,7 @@ namespace osu.Game.Overlays.Chat
username.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint); username.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint);
closeButton.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint); closeButton.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint);
closeButton.FadeIn(activate_length, Easing.OutQuint); closeButton.FadeIn(activate_length, Easing.OutQuint);
TweenEdgeEffectTo(activateEdgeEffect, activate_length); // TweenEdgeEffectTo(activateEdgeEffect, activate_length);
} }
private readonly EdgeEffectParameters deactivateEdgeEffect = new EdgeEffectParameters private readonly EdgeEffectParameters deactivateEdgeEffect = new EdgeEffectParameters
@ -187,7 +196,7 @@ namespace osu.Game.Overlays.Chat
username.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint); username.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint);
closeButton.FadeOut(deactivate_length, Easing.OutQuint); closeButton.FadeOut(deactivate_length, Easing.OutQuint);
closeButton.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint); closeButton.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint);
TweenEdgeEffectTo(deactivateEdgeEffect, deactivate_length); // TweenEdgeEffectTo(deactivateEdgeEffect, deactivate_length);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -32,7 +32,7 @@ namespace osu.Game.Overlays
private ChatManager chatManager; private ChatManager chatManager;
private readonly Container<DrawableChat> currentChannelContainer; private readonly Container<DrawableChat> currentChatContainer;
private readonly List<DrawableChat> loadedChannels = new List<DrawableChat>(); private readonly List<DrawableChat> loadedChannels = new List<DrawableChat>();
private readonly LoadingAnimation loading; private readonly LoadingAnimation loading;
@ -45,8 +45,7 @@ namespace osu.Game.Overlays
public const float TAB_AREA_HEIGHT = 50; public const float TAB_AREA_HEIGHT = 50;
private readonly ChannelTabControl channelTabs; private readonly ChatTabControl chatTabControl;
private readonly UserChatTabControl userTabs;
private readonly Container chatContainer; private readonly Container chatContainer;
private readonly Container tabsArea; private readonly Container tabsArea;
@ -105,7 +104,7 @@ namespace osu.Game.Overlays
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
currentChannelContainer = new Container<DrawableChat> currentChatContainer = new Container<DrawableChat>
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding Padding = new MarginPadding
@ -155,15 +154,16 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black, Colour = Color4.Black,
}, },
channelTabs = new ChannelTabControl chatTabControl = new ChatTabControl
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
OnRequestLeave = channel => chatManager.JoinedChannels.Remove(channel), OnRequestLeave = chat =>
},
userTabs = new UserChatTabControl
{ {
RelativeSizeAxes = Axes.Both, if (chat is ChannelChat channelChat)
OnRequestLeave = privateChat => chatManager.OpenedUserChats.Remove(privateChat), chatManager.JoinedChannels.Remove(channelChat);
if (chat is UserChat userChat)
chatManager.OpenedUserChats.Remove(userChat);
}
} }
} }
}, },
@ -171,12 +171,11 @@ namespace osu.Game.Overlays
}, },
}; };
userTabs.Current.ValueChanged += user => chatManager.CurrentChat.Value = user; chatTabControl.Current.ValueChanged += chat => chatManager.CurrentChat.Value = chat;
channelTabs.Current.ValueChanged += newChannel => chatManager.CurrentChat.Value = newChannel; chatTabControl.channelTabControl.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden;
channelTabs.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden;
channelSelection.StateChanged += state => channelSelection.StateChanged += state =>
{ {
channelTabs.ChannelSelectorActive.Value = state == Visibility.Visible; chatTabControl.channelTabControl.ChannelSelectorActive.Value = state == Visibility.Visible;
if (state == Visibility.Visible) if (state == Visibility.Visible)
{ {
@ -214,19 +213,16 @@ namespace osu.Game.Overlays
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
foreach (ChannelChat newChannel in args.NewItems) foreach (ChannelChat newChannel in args.NewItems)
{ {
channelTabs.AddItem(newChannel); chatTabControl.AddItem(newChannel);
newChannel.Joined.Value = true; newChannel.Joined.Value = true;
if (chatManager.CurrentChat.Value == null) //if (chatManager.CurrentChat.Value == null)
chatManager.CurrentChat.Value = newChannel; // chatManager.CurrentChat.Value = newChannel;
if (chatManager.CurrentChat.Value == newChannel)
channelTabs.Current.Value = newChannel;
} }
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
foreach (ChannelChat removedChannel in args.OldItems) foreach (ChannelChat removedChannel in args.OldItems)
{ {
channelTabs.RemoveItem(removedChannel); chatTabControl.RemoveItem(removedChannel);
loadedChannels.Remove(loadedChannels.Find(c => c.Chat == removedChannel )); loadedChannels.Remove(loadedChannels.Find(c => c.Chat == removedChannel ));
removedChannel.Joined.Value = false; removedChannel.Joined.Value = false;
if (chatManager.CurrentChat.Value == removedChannel) if (chatManager.CurrentChat.Value == removedChannel)
@ -241,19 +237,19 @@ namespace osu.Game.Overlays
if (chat == null) if (chat == null)
{ {
textbox.Current.Disabled = true; textbox.Current.Disabled = true;
currentChannelContainer.Clear(false); currentChatContainer.Clear(false);
chatTabControl.Current.Value = null;
return; return;
} }
textbox.Current.Disabled = chat.ReadOnly; textbox.Current.Disabled = chat.ReadOnly;
userTabs.DeselectAll(); Scheduler.Add(() => chatTabControl.Current.Value = chat);
channelTabs.DeselectAll();
var loaded = loadedChannels.Find(d => d.Chat == chat); var loaded = loadedChannels.Find(d => d.Chat == chat);
if (loaded == null) if (loaded == null)
{ {
currentChannelContainer.FadeOut(500, Easing.OutQuint); currentChatContainer.FadeOut(500, Easing.OutQuint);
loading.Show(); loading.Show();
loaded = new DrawableChat(chat); loaded = new DrawableChat(chat);
@ -262,15 +258,15 @@ namespace osu.Game.Overlays
{ {
loading.Hide(); loading.Hide();
currentChannelContainer.Clear(false); currentChatContainer.Clear(false);
currentChannelContainer.Add(loaded); currentChatContainer.Add(loaded);
currentChannelContainer.FadeIn(500, Easing.OutQuint); currentChatContainer.FadeIn(500, Easing.OutQuint);
}); });
} }
else else
{ {
currentChannelContainer.Clear(false); currentChatContainer.Clear(false);
currentChannelContainer.Add(loaded); currentChatContainer.Add(loaded);
} }
} }
@ -371,18 +367,15 @@ namespace osu.Game.Overlays
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
foreach (UserChat chat in args.NewItems) foreach (UserChat chat in args.NewItems)
{ {
userTabs.AddItem(args.NewItems[0] as UserChat); chatTabControl.AddItem(args.NewItems[0] as UserChat);
if (chatManager.CurrentChat.Value == chat) if (chatManager.CurrentChat.Value == chat)
userTabs.Current.Value = chat; chatTabControl.Current.Value = chat;
} }
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
foreach (UserChat chat in args.OldItems) foreach (UserChat chat in args.OldItems)
userTabs.RemoveItem(chat); chatTabControl.RemoveItem(chat);
break;
case NotifyCollectionChangedAction.Reset:
userTabs.Clear();
break; break;
} }
} }