1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-24 23:53:02 +08:00
osu-lazer/osu.Game/Overlays/Chat/ChatTextBar.cs
2024-05-03 12:31:19 +08:00

186 lines
6.9 KiB
C#

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.Chat;
using osu.Game.Resources.Localisation.Web;
using osuTK;
namespace osu.Game.Overlays.Chat
{
public partial class ChatTextBar : Container
{
public const float HEIGHT = 40;
public readonly BindableBool ShowSearch = new BindableBool();
public event Action<string>? OnChatMessageCommitted;
public event Action<string>? OnSearchTermsChanged;
public void TextBoxTakeFocus() => chatTextBox.TakeFocus();
public void TextBoxKillFocus() => chatTextBox.KillFocus();
[Resolved]
private Bindable<Channel> currentChannel { get; set; } = null!;
private Container chattingTextContainer = null!;
private OsuSpriteText chattingText = null!;
private Container searchIconContainer = null!;
private ChatTextBox chatTextBox = null!;
private const float chatting_text_width = 220;
private const float search_icon_width = 40;
private const float padding = 5;
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Axes.X;
Height = HEIGHT;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
},
new GridContainer
{
RelativeSizeAxes = Axes.Both,
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
},
Content = new[]
{
new Drawable[]
{
chattingTextContainer = new Container
{
RelativeSizeAxes = Axes.Y,
Width = chatting_text_width,
Masking = true,
Padding = new MarginPadding { Horizontal = padding },
Child = chattingText = new TruncatingSpriteText
{
MaxWidth = chatting_text_width - padding * 2,
Font = OsuFont.Torus,
Colour = colourProvider.Background1,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
},
},
searchIconContainer = new Container
{
RelativeSizeAxes = Axes.Y,
Width = search_icon_width,
Child = new SpriteIcon
{
Icon = FontAwesome.Solid.Search,
Origin = Anchor.CentreRight,
Anchor = Anchor.CentreRight,
Size = new Vector2(OsuFont.DEFAULT_FONT_SIZE),
Margin = new MarginPadding { Right = 2 },
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = padding },
Child = chatTextBox = new ChatTextBox
{
FontSize = OsuFont.DEFAULT_FONT_SIZE,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.X,
ShowSearch = { BindTarget = ShowSearch },
HoldFocus = true,
ReleaseFocusOnCommit = false,
},
},
},
},
},
};
}
protected override void LoadComplete()
{
base.LoadComplete();
chatTextBox.Current.ValueChanged += chatTextBoxChange;
chatTextBox.OnCommit += chatTextBoxCommit;
ShowSearch.BindValueChanged(change =>
{
bool showSearch = change.NewValue;
chattingTextContainer.FadeTo(showSearch ? 0 : 1);
searchIconContainer.FadeTo(showSearch ? 1 : 0);
if (showSearch)
OnSearchTermsChanged?.Invoke(chatTextBox.Current.Value);
}, true);
currentChannel.BindValueChanged(change =>
{
Channel newChannel = change.NewValue;
switch (newChannel?.Type)
{
case null:
chattingText.Text = string.Empty;
break;
case ChannelType.PM:
chattingText.Text = ChatStrings.TalkingWith(newChannel.Name);
break;
default:
chattingText.Text = ChatStrings.TalkingIn(newChannel.Name);
break;
}
if (change.OldValue != null)
chatTextBox.Current.UnbindFrom(change.OldValue.TextBoxMessage);
if (newChannel != null)
{
// change length limit first before binding to avoid accidentally truncating pending message from new channel.
chatTextBox.LengthLimit = newChannel.MessageLengthLimit;
chatTextBox.Current.BindTo(newChannel.TextBoxMessage);
}
}, true);
}
private void chatTextBoxChange(ValueChangedEvent<string> change)
{
if (ShowSearch.Value)
OnSearchTermsChanged?.Invoke(change.NewValue);
}
private void chatTextBoxCommit(TextBox sender, bool newText)
{
if (ShowSearch.Value)
return;
OnChatMessageCommitted?.Invoke(sender.Text);
sender.Text = string.Empty;
}
}
}