Files
tbd-station-14/Content.Client/RCD/RCDMenu.xaml.cs
metalgearsloth cbf329a82d Remove some BUI boilerplate (#28399)
* Remove some BUI boilerplate

- The disposals overrides got removed due to the helper method handling it.
- Replace window creation with CreateWindow helper.
- Fixed some stinky code which would cause exceptions.

* More

* moar

* weh

* done

* More BUIs

* More updates

* weh

* moar

* look who it is

* weh

* merge

* weh

* fixes
2024-07-20 15:40:16 +10:00

180 lines
5.5 KiB
C#

using Content.Client.UserInterface.Controls;
using Content.Shared.Popups;
using Content.Shared.RCD;
using Content.Shared.RCD.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using System.Numerics;
namespace Content.Client.RCD;
[GenerateTypedNameReferences]
public sealed partial class RCDMenu : RadialMenu
{
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
private SharedPopupSystem _popup;
private SpriteSystem _sprites;
public event Action<ProtoId<RCDPrototype>>? SendRCDSystemMessageAction;
private EntityUid _owner;
public RCDMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
_popup = _entManager.System<SharedPopupSystem>();
_sprites = _entManager.System<SpriteSystem>();
OnChildAdded += AddRCDMenuButtonOnClickActions;
}
public void SetEntity(EntityUid uid)
{
_owner = uid;
}
public void Refresh()
{
// Find the main radial container
var main = FindControl<RadialContainer>("Main");
// Populate secondary radial containers
if (!_entManager.TryGetComponent<RCDComponent>(_owner, out var rcd))
return;
foreach (var protoId in rcd.AvailablePrototypes)
{
if (!_protoManager.TryIndex(protoId, out var proto))
continue;
if (proto.Mode == RcdMode.Invalid)
continue;
var parent = FindControl<RadialContainer>(proto.Category);
var tooltip = Loc.GetString(proto.SetName);
if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) &&
proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto))
{
tooltip = Loc.GetString(entProto.Name);
}
tooltip = OopsConcat(char.ToUpper(tooltip[0]).ToString(), tooltip.Remove(0, 1));
var button = new RCDMenuButton()
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = tooltip,
ProtoId = protoId,
};
if (proto.Sprite != null)
{
var tex = new TextureRect()
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = _sprites.Frame0(proto.Sprite),
TextureScale = new Vector2(2f, 2f),
};
button.AddChild(tex);
}
parent.AddChild(button);
// Ensure that the button that transitions the menu to the associated category layer
// is visible in the main radial container (as these all start with Visible = false)
foreach (var child in main.Children)
{
var castChild = child as RadialMenuTextureButton;
if (castChild is not RadialMenuTextureButton)
continue;
if (castChild.TargetLayer == proto.Category)
{
castChild.Visible = true;
break;
}
}
}
// Set up menu actions
foreach (var child in Children)
{
AddRCDMenuButtonOnClickActions(child);
}
}
private static string OopsConcat(string a, string b)
{
// This exists to prevent Roslyn being clever and compiling something that fails sandbox checks.
return a + b;
}
private void AddRCDMenuButtonOnClickActions(Control control)
{
var radialContainer = control as RadialContainer;
if (radialContainer == null)
return;
foreach (var child in radialContainer.Children)
{
var castChild = child as RCDMenuButton;
if (castChild == null)
continue;
castChild.OnButtonUp += _ =>
{
SendRCDSystemMessageAction?.Invoke(castChild.ProtoId);
if (_playerManager.LocalSession?.AttachedEntity != null &&
_protoManager.TryIndex(castChild.ProtoId, out var proto))
{
var msg = Loc.GetString("rcd-component-change-mode", ("mode", Loc.GetString(proto.SetName)));
if (proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject)
{
var name = Loc.GetString(proto.SetName);
if (proto.Prototype != null &&
_protoManager.TryIndex(proto.Prototype, out var entProto))
name = entProto.Name;
msg = Loc.GetString("rcd-component-change-build-mode", ("name", name));
}
// Popup message
_popup.PopupClient(msg, _owner, _playerManager.LocalSession.AttachedEntity);
}
Close();
};
}
}
}
public sealed class RCDMenuButton : RadialMenuTextureButton
{
public ProtoId<RCDPrototype> ProtoId { get; set; }
public RCDMenuButton()
{
}
}