From 2f635fa8546bbd5efabb6ecb60b0c32792c32703 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Tue, 7 Jun 2022 01:37:46 +0100 Subject: [PATCH] Refactor `ChatLine` and fix `DrawableChannel` flow padding Refactors `ChatLine` component to use more sensible override properties and layout using grid container. Moves creation of username component into its own method to simplify BDL. Updates padding of base `DrawableChannel` flow padding. Removes usage of `ChatOverlayDrawableChannel` since it's overrides are no longer needed. Updates usage of `StandAloneChatDisplay` to use new override properties of `DrawableChannel`. --- .../Visual/Online/TestSceneChatOverlay.cs | 6 +- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 19 +- osu.Game/Overlays/Chat/ChatLine.cs | 192 +++++++++--------- .../Chat/ChatOverlayDrawableChannel.cs | 39 ---- osu.Game/Overlays/Chat/DaySeparator.cs | 2 +- osu.Game/Overlays/Chat/DrawableChannel.cs | 2 +- osu.Game/Overlays/ChatOverlay.cs | 12 +- 7 files changed, 114 insertions(+), 158 deletions(-) delete mode 100644 osu.Game/Overlays/Chat/ChatOverlayDrawableChannel.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 2cf1114f30..97221329f5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -572,15 +572,15 @@ namespace osu.Game.Tests.Visual.Online public SlowLoadingDrawableChannel GetSlowLoadingChannel(Channel channel) => DrawableChannels.OfType().Single(c => c.Channel == channel); - protected override ChatOverlayDrawableChannel CreateDrawableChannel(Channel newChannel) + protected override DrawableChannel CreateDrawableChannel(Channel newChannel) { return SlowLoading ? new SlowLoadingDrawableChannel(newChannel) - : new ChatOverlayDrawableChannel(newChannel); + : new DrawableChannel(newChannel); } } - private class SlowLoadingDrawableChannel : ChatOverlayDrawableChannel + private class SlowLoadingDrawableChannel : DrawableChannel { public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim(); diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index f57ffcfe25..bbfffea6fd 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -160,13 +160,6 @@ namespace osu.Game.Online.Chat { } - [BackgroundDependencyLoader] - private void load() - { - // TODO: Remove once DrawableChannel & ChatLine padding is fixed - ChatLineFlow.Padding = new MarginPadding { Horizontal = 0 }; - } - protected override ChatLine CreateChatLine(Message m) => CreateChatLineAction(m); protected override DaySeparator CreateDaySeparator(DateTimeOffset time) => new StandAloneDaySeparator(time); @@ -176,8 +169,8 @@ namespace osu.Game.Online.Chat { protected override float TextSize => 14; protected override float LineHeight => 1; - protected override float Spacing => 10; - protected override float DateAlign => 120; + protected override float Spacing => 5; + protected override float DateAlign => 125; public StandAloneDaySeparator(DateTimeOffset time) : base(time) @@ -189,17 +182,15 @@ namespace osu.Game.Online.Chat { Height = 25; Colour = colours.Yellow; - // TODO: Remove once DrawableChannel & ChatLine padding is fixed - Padding = new MarginPadding { Horizontal = 10 }; } } protected class StandAloneMessage : ChatLine { protected override float TextSize => 15; - protected override float HorizontalPadding => 10; - protected override float MessagePadding => 120; - protected override float TimestampPadding => 50; + protected override float Spacing => 5; + protected override float TimestampWidth => 45; + protected override float UsernameWidth => 75; public StandAloneMessage(Message message) : base(message) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index a1d8cd5d38..13f66089d9 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -26,22 +26,14 @@ namespace osu.Game.Overlays.Chat { public class ChatLine : CompositeDrawable { - public const float LEFT_PADDING = default_message_padding + default_horizontal_padding * 2; - - private const float default_message_padding = 200; - - protected virtual float MessagePadding => default_message_padding; - - private const float default_timestamp_padding = 65; - - protected virtual float TimestampPadding => default_timestamp_padding; - - private const float default_horizontal_padding = 15; - - protected virtual float HorizontalPadding => default_horizontal_padding; - protected virtual float TextSize => 20; + protected virtual float Spacing => 15; + + protected virtual float TimestampWidth => 60; + + protected virtual float UsernameWidth => 130; + private Color4 usernameColour; private OsuSpriteText timestamp; @@ -49,7 +41,6 @@ namespace osu.Game.Overlays.Chat public ChatLine(Message message) { Message = message; - Padding = new MarginPadding { Left = HorizontalPadding, Right = HorizontalPadding }; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; } @@ -90,88 +81,45 @@ namespace osu.Game.Overlays.Chat ? Color4Extensions.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; - Drawable effectedUsername = username = new OsuSpriteText + InternalChild = new GridContainer { - Shadow = false, - Colour = senderHasColour ? colours.ChatBlue : usernameColour, - Truncate = true, - EllipsisString = "… :", - Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - MaxWidth = MessagePadding - TimestampPadding - }; - - if (senderHasColour) - { - // Background effect - effectedUsername = new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + ColumnDimensions = new[] { - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - EdgeEffect = new EdgeEffectParameters - { - Roundness = 1, - Radius = 1, - Colour = Color4.Black.Opacity(0.3f), - Offset = new Vector2(0, 1), - Type = EdgeEffectType.Shadow, - }, - Child = new Container - { - AutoSizeAxes = Axes.Both, - Y = 0, - Masking = true, - CornerRadius = 4, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = usernameColour, - }, - new Container - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, - Child = username - } - } - } - }; - } - - InternalChildren = new Drawable[] - { - new Container - { - Size = new Vector2(MessagePadding, TextSize), - Children = new Drawable[] - { - timestamp = new OsuSpriteText - { - Shadow = false, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true) - }, - new MessageSender(message.Sender) - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - Child = effectedUsername, - }, - } + new Dimension(GridSizeMode.Absolute, TimestampWidth + Spacing + UsernameWidth + Spacing), + new Dimension(), }, - new Container + Content = new[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = MessagePadding + HorizontalPadding }, - Children = new Drawable[] + new Drawable[] { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + timestamp = new OsuSpriteText + { + Shadow = false, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), + MaxWidth = TimestampWidth, + }, + new MessageSender(message.Sender) + { + Width = UsernameWidth, + AutoSizeAxes = Axes.Y, + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Child = createUsername(), + Margin = new MarginPadding { Horizontal = Spacing }, + }, + }, + }, ContentFlow = new LinkFlowContainer(t => { t.Shadow = false; @@ -190,7 +138,7 @@ namespace osu.Game.Overlays.Chat AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, } - } + }, } }; } @@ -233,7 +181,7 @@ namespace osu.Game.Overlays.Chat timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = $@"{message.Sender.Username}" + (senderHasColour || message.IsAction ? "" : ":"); + username.Text = $@"{message.Sender.Username}"; // remove non-existent channels from the link list message.Links.RemoveAll(link => link.Action == LinkAction.OpenChannel && chatManager?.AvailableChannels.Any(c => c.Name == link.Argument.ToString()) != true); @@ -242,6 +190,62 @@ namespace osu.Game.Overlays.Chat ContentFlow.AddLinks(message.DisplayContent, message.Links); } + private Drawable createUsername() + { + username = new OsuSpriteText + { + Shadow = false, + Colour = senderHasColour ? colours.ChatBlue : usernameColour, + Truncate = true, + EllipsisString = "…", + Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + MaxWidth = UsernameWidth, + }; + + if (!senderHasColour) + return username; + + // Background effect + return new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + EdgeEffect = new EdgeEffectParameters + { + Roundness = 1, + Radius = 1, + Colour = Color4.Black.Opacity(0.3f), + Offset = new Vector2(0, 1), + Type = EdgeEffectType.Shadow, + }, + Child = new Container + { + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = usernameColour, + }, + new Container + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, + Child = username + } + } + } + }; + } + private class MessageSender : OsuClickableContainer, IHasContextMenu { private readonly APIUser sender; diff --git a/osu.Game/Overlays/Chat/ChatOverlayDrawableChannel.cs b/osu.Game/Overlays/Chat/ChatOverlayDrawableChannel.cs deleted file mode 100644 index a5d22f678e..0000000000 --- a/osu.Game/Overlays/Chat/ChatOverlayDrawableChannel.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable enable - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Online.Chat; - -namespace osu.Game.Overlays.Chat -{ - public class ChatOverlayDrawableChannel : DrawableChannel - { - public ChatOverlayDrawableChannel(Channel channel) - : base(channel) - { - } - - [BackgroundDependencyLoader] - private void load() - { - // TODO: Remove once DrawableChannel & ChatLine padding is fixed - ChatLineFlow.Padding = new MarginPadding(0); - } - - protected override DaySeparator CreateDaySeparator(DateTimeOffset time) => new ChatOverlayDaySeparator(time); - - private class ChatOverlayDaySeparator : DaySeparator - { - public ChatOverlayDaySeparator(DateTimeOffset time) - : base(time) - { - // TODO: Remove once DrawableChannel & ChatLine padding is fixed - Padding = new MarginPadding { Horizontal = 15 }; - } - } - } -} diff --git a/osu.Game/Overlays/Chat/DaySeparator.cs b/osu.Game/Overlays/Chat/DaySeparator.cs index 2e3796151c..9ae35b0c38 100644 --- a/osu.Game/Overlays/Chat/DaySeparator.cs +++ b/osu.Game/Overlays/Chat/DaySeparator.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Chat protected virtual float LineHeight => 2; - protected virtual float DateAlign => 200; + protected virtual float DateAlign => 205; protected virtual float Spacing => 15; diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index f0d4d12f4f..c3a341bca4 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Chat Padding = new MarginPadding { Bottom = 5 }, Child = ChatLineFlow = new FillFlowContainer { - Padding = new MarginPadding { Horizontal = 15 }, + Padding = new MarginPadding { Horizontal = 10 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 02769b5d68..f04bf76c18 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -38,9 +38,9 @@ namespace osu.Game.Overlays private LoadingLayer loading = null!; private ChannelListing channelListing = null!; private ChatTextBar textBar = null!; - private Container currentChannelContainer = null!; + private Container currentChannelContainer = null!; - private readonly Dictionary loadedChannels = new Dictionary(); + private readonly Dictionary loadedChannels = new Dictionary(); protected IEnumerable DrawableChannels => loadedChannels.Values; @@ -126,7 +126,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4, }, - currentChannelContainer = new Container + currentChannelContainer = new Container { RelativeSizeAxes = Axes.Both, }, @@ -313,7 +313,7 @@ namespace osu.Game.Overlays loading.Show(); // Ensure the drawable channel is stored before async load to prevent double loading - ChatOverlayDrawableChannel drawableChannel = CreateDrawableChannel(newChannel); + DrawableChannel drawableChannel = CreateDrawableChannel(newChannel); loadedChannels.Add(newChannel, drawableChannel); LoadComponentAsync(drawableChannel, loadedDrawable => @@ -338,7 +338,7 @@ namespace osu.Game.Overlays channelManager.MarkChannelAsRead(newChannel); } - protected virtual ChatOverlayDrawableChannel CreateDrawableChannel(Channel newChannel) => new ChatOverlayDrawableChannel(newChannel); + protected virtual DrawableChannel CreateDrawableChannel(Channel newChannel) => new DrawableChannel(newChannel); private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args) { @@ -361,7 +361,7 @@ namespace osu.Game.Overlays if (loadedChannels.ContainsKey(channel)) { - ChatOverlayDrawableChannel loaded = loadedChannels[channel]; + DrawableChannel loaded = loadedChannels[channel]; loadedChannels.Remove(channel); // DrawableChannel removed from cache must be manually disposed loaded.Dispose();