Hud refactor (#7202)

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: Jezithyr <jmaster9999@gmail.com>
Co-authored-by: Jezithyr <Jezithyr@gmail.com>
Co-authored-by: Visne <39844191+Visne@users.noreply.github.com>
Co-authored-by: wrexbe <wrexbe@protonmail.com>
Co-authored-by: wrexbe <81056464+wrexbe@users.noreply.github.com>
This commit is contained in:
Jezithyr
2022-10-12 01:16:23 -07:00
committed by GitHub
parent d09fbc1849
commit 571dd4e6d5
168 changed files with 6940 additions and 7817 deletions

View File

@@ -0,0 +1,78 @@
using Content.Client.UserInterface.Controls;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
public sealed class InventoryDisplay : LayoutContainer
{
private int Columns = 0;
private int Rows = 0;
private const int MarginThickness = 10;
private const int ButtonSpacing = 5;
private const int ButtonSize = 75;
private readonly Control resizer;
private readonly Dictionary<string, (SlotControl, Vector2i)> _buttons = new();
public InventoryDisplay()
{
resizer = new Control();
AddChild(resizer);
}
public SlotControl? AddButton(SlotControl newButton, Vector2i buttonOffset)
{
AddChild(newButton);
HorizontalExpand = true;
VerticalExpand = true;
InheritChildMeasure = true;
if (!_buttons.TryAdd(newButton.SlotName, (newButton, buttonOffset)))
Logger.Warning("Tried to add button without a slot!");
SetPosition(newButton, buttonOffset * ButtonSize + new Vector2(ButtonSpacing, ButtonSpacing));
UpdateSizeData(buttonOffset);
return newButton;
}
public SlotControl? GetButton(string slotName)
{
return !_buttons.TryGetValue(slotName, out var foundButton) ? null : foundButton.Item1;
}
private void UpdateSizeData(Vector2i buttonOffset)
{
var (x, _) = buttonOffset;
if (x > Columns)
Columns = x;
var (_, y) = buttonOffset;
if (y > Rows)
Rows = y;
resizer.SetHeight = (Rows + 1) * (ButtonSize + ButtonSpacing);
resizer.SetWidth = (Columns + 1) * (ButtonSize + ButtonSpacing);
}
public bool TryGetButton(string slotName, out SlotControl? button)
{
var success = _buttons.TryGetValue(slotName, out var buttonData);
button = buttonData.Item1;
return success;
}
public void RemoveButton(string slotName)
{
if (!_buttons.Remove(slotName))
return;
//recalculate the size of the control when a slot is removed
Columns = 0;
Rows = 0;
foreach (var (_, (_, buttonOffset)) in _buttons)
{
UpdateSizeData(buttonOffset);
}
}
public void ClearButtons()
{
Children.Clear();
}
}

View File

@@ -0,0 +1,30 @@
using Content.Client.UserInterface.Controls;
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
public sealed class ItemSlotButtonContainer : ItemSlotUIContainer<SlotControl>
{
private readonly InventoryUIController _inventoryController;
private string _slotGroup = "";
public string SlotGroup
{
get => _slotGroup;
set
{
_inventoryController.RemoveSlotGroup(SlotGroup);
_slotGroup = value;
_inventoryController.RegisterSlotGroupContainer(this);
}
}
public ItemSlotButtonContainer()
{
_inventoryController = UserInterfaceManager.GetUIController<InventoryUIController>();
}
~ItemSlotButtonContainer()
{
_inventoryController.RemoveSlotGroup(SlotGroup);
}
}

View File

@@ -0,0 +1,129 @@
using System.Diagnostics.CodeAnalysis;
using Content.Client.UserInterface.Controls;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
public interface IItemslotUIContainer
{
public bool TryRegisterButton(SlotControl control, string newSlotName);
public bool TryAddButton(SlotControl control);
}
[Virtual]
public abstract class ItemSlotUIContainer<T> : GridContainer, IItemslotUIContainer where T : SlotControl
{
protected readonly Dictionary<string, T> Buttons = new();
public virtual bool TryAddButton(T newButton, out T button)
{
var tempButton = AddButton(newButton);
if (tempButton == null)
{
button = newButton;
return false;
}
button = newButton;
return true;
}
public void ClearButtons()
{
foreach (var button in Buttons.Values)
{
button.Dispose();
}
Buttons.Clear();
}
public bool TryRegisterButton(SlotControl control, string newSlotName)
{
if (newSlotName == "")
return false;
if (!(control is T slotButton))
return false;
if (Buttons.TryGetValue(newSlotName, out var foundButton))
{
if (control == foundButton)
return true; //if the slotName is already set do nothing
throw new Exception("Could not update button to slot:" + newSlotName + " slot already assigned!");
}
Buttons.Remove(slotButton.SlotName);
AddButton(slotButton);
return true;
}
public bool TryAddButton(SlotControl control)
{
if (control is not T newButton)
return false;
return AddButton(newButton) != null;
}
public virtual T? AddButton(T newButton)
{
if (!Children.Contains(newButton) && newButton.Parent == null && newButton.SlotName != "")
AddChild(newButton);
return AddButtonToDict(newButton);
}
protected virtual T? AddButtonToDict(T newButton)
{
if (newButton.SlotName == "")
{
Logger.Warning("Could not add button " + newButton.Name + "No slotname");
}
return !Buttons.TryAdd(newButton.SlotName, newButton) ? null : newButton;
}
public virtual void RemoveButton(string slotName)
{
if (!Buttons.TryGetValue(slotName, out var button))
return;
RemoveButton(button);
}
public virtual void RemoveButtons(params string[] slotNames)
{
foreach (var slotName in slotNames)
{
RemoveButton(slotName);
}
}
public virtual void RemoveButtons(params T?[] buttons)
{
foreach (var button in buttons)
{
if (button != null)
RemoveButton(button);
}
}
protected virtual void RemoveButtonFromDict(T button)
{
Buttons.Remove(button.SlotName);
}
public virtual void RemoveButton(T button)
{
RemoveButtonFromDict(button);
Children.Remove(button);
button.Dispose();
}
public virtual T? GetButton(string slotName)
{
return !Buttons.TryGetValue(slotName, out var button) ? null : button;
}
public virtual bool TryGetButton(string slotName, [NotNullWhen(true)] out T? button)
{
return (button = GetButton(slotName)) != null;
}
}

View File

@@ -0,0 +1,24 @@
<controls:ItemStatusPanel
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Controls"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
MinSize="150 0">
<PanelContainer
Name="Panel"
ModulateSelfOverride="#FFFFFFE6"
HorizontalExpand="True">
<PanelContainer.PanelOverride>
<graphics:StyleBoxTexture
ContentMarginLeftOverride="6"
ContentMarginRightOverride="6"
ContentMarginTopOverride="4"
ContentMarginBottomOverride="4" />
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Vertical" SeparationOverride="0">
<BoxContainer Name="StatusContents" Orientation="Vertical"/>
<Label Name="ItemNameLabel" ClipText="True" StyleClasses="ItemStatus"/>
</BoxContainer>
</PanelContainer>
</controls:ItemStatusPanel>

View File

@@ -0,0 +1,138 @@
using Content.Client.Items;
using Content.Client.Resources;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using static Content.Client.IoC.StaticIoC;
namespace Content.Client.UserInterface.Systems.Inventory.Controls;
[GenerateTypedNameReferences]
public sealed partial class ItemStatusPanel : BoxContainer
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[ViewVariables] private EntityUid? _entity;
public ItemStatusPanel()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
SetSide(HandLocation.Middle);
}
public void SetSide(HandLocation location)
{
string texture;
StyleBox.Margin cutOut;
StyleBox.Margin flat;
Label.AlignMode textAlign;
switch (location)
{
case HandLocation.Left:
texture = "/Textures/Interface/Nano/item_status_right.svg.96dpi.png";
cutOut = StyleBox.Margin.Left | StyleBox.Margin.Top;
flat = StyleBox.Margin.Right | StyleBox.Margin.Bottom;
textAlign = Label.AlignMode.Right;
break;
case HandLocation.Middle:
texture = "/Textures/Interface/Nano/item_status_middle.svg.96dpi.png";
cutOut = StyleBox.Margin.Right | StyleBox.Margin.Top;
flat = StyleBox.Margin.Left | StyleBox.Margin.Bottom;
textAlign = Label.AlignMode.Left;
break;
case HandLocation.Right:
texture = "/Textures/Interface/Nano/item_status_left.svg.96dpi.png";
cutOut = StyleBox.Margin.Right | StyleBox.Margin.Top;
flat = StyleBox.Margin.Left | StyleBox.Margin.Bottom;
textAlign = Label.AlignMode.Left;
break;
default:
throw new ArgumentOutOfRangeException(nameof(location), location, null);
}
var panel = (StyleBoxTexture) Panel.PanelOverride!;
panel.Texture = ResC.GetTexture(texture);
panel.SetPatchMargin(flat, 2);
panel.SetPatchMargin(cutOut, 13);
ItemNameLabel.Align = textAlign;
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateItemName();
}
public void Update(EntityUid? entity)
{
if (entity == null)
{
ClearOldStatus();
_entity = null;
Panel.Visible = false;
return;
}
if (entity != _entity)
{
_entity = entity.Value;
BuildNewEntityStatus();
UpdateItemName();
}
Panel.Visible = true;
}
private void UpdateItemName()
{
if (_entity == null)
return;
if (!_entityManager.TryGetComponent<MetaDataComponent>(_entity, out var meta) || meta.Deleted)
{
Update(null);
return;
}
if (_entityManager.TryGetComponent(_entity, out HandVirtualItemComponent? virtualItem)
&& _entityManager.EntityExists(virtualItem.BlockingEntity))
{
// Uses identity because we can be blocked by pulling someone
ItemNameLabel.Text = Identity.Name(virtualItem.BlockingEntity, _entityManager);
}
else
{
ItemNameLabel.Text = Identity.Name(_entity.Value, _entityManager);
}
}
private void ClearOldStatus()
{
StatusContents.RemoveAllChildren();
}
private void BuildNewEntityStatus()
{
DebugTools.AssertNotNull(_entity);
ClearOldStatus();
var collectMsg = new ItemStatusCollectMessage();
_entityManager.EventBus.RaiseLocalEvent(_entity!.Value, collectMsg, true);
foreach (var control in collectMsg.Controls)
{
StatusContents.AddChild(control);
}
}
}