using Content.Client.UserInterface.ControlExtensions;
using Content.Client.UserInterface.RichText;
using Content.Shared.Chat;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Input;
using Robust.Shared.Utility;
namespace Content.Client.UserInterface.Controls;
///
/// Carries link data parsed and resolved from a TextLink ,
/// only one LinkType field per link should be populated at a time.
///
public sealed partial class TextLinkLabel : Label
{
public string? LinkString { get; init; } // default links
public NetEntity? LinkEntity { get; init; } // entity links
public Color LinkColor { get; set; }
[Dependency] private IEntityManager _entity = default!;
private bool _canClickLink;
public TextLinkLabel()
{
IoCManager.InjectDependencies(this);
OnKeyBindDown += OnKeybindDown;
OnMouseEntered += _ => OnHoverChanged(true);
OnMouseExited += _ => OnHoverChanged(false);
}
///
/// Refreshes the label's properties based on the current link target
/// and the viewer's permission to follow it.
Call after construction,
/// and whenever that permission could have changed.
///
/// Whether the label should be shown at all. Defaults to true.
/// Additional override to force the label non-clickable. Defaults to true.
public void UpdateLabelProperties(SharedChatSystem? chatSystem, bool? visible = null, bool? clickable = null)
{
visible ??= true;
Visible = visible.Value;
clickable ??= true;
_canClickLink = (LinkString != null || (LinkEntity is { } netEntity && (chatSystem?.CanClickMessageSender(netEntity) ?? false))) && (bool)clickable;
MouseFilter = _canClickLink ? MouseFilterMode.Stop : MouseFilterMode.Ignore;
DefaultCursorShape = _canClickLink ? CursorShape.Hand : CursorShape.Arrow;
OnHoverChanged(false);
}
private void OnHoverChanged(bool hovering)
{
FontColorOverride = (_canClickLink, hovering) switch
{
(true, true) => Color.LightSkyBlue, // clickable and currently hovered
_ => LinkColor, // not clickable, or not hovered
};
}
///
/// Delegates click to the nearest ancestor ILinkClickHandler or IEntityLinkClickHandler;
/// TextLinkLabel has no idea what a click actually does.
///
private void OnKeybindDown(GUIBoundKeyEventArgs args)
{
if (args.Function != EngineKeyFunctions.UIClick)
return;
if (LinkString is null && LinkEntity is null)
return;
if (LinkEntity is { } entity &&
this.TryGetParentHandler(out var entityLinkClickHandler))
{
entityLinkClickHandler.HandleClick(entity);
}
else if (LinkString != null && this.TryGetParentHandler(out var linkClickHandler))
{
linkClickHandler.HandleClick(LinkString);
}
}
}