Improved Inventory / Hand Slots UI (#2965)

This commit is contained in:
chairbender
2021-01-20 00:32:44 -08:00
committed by GitHub
parent 02ea6ce57c
commit f9670d36c4
15 changed files with 304 additions and 152 deletions

View File

@@ -66,7 +66,8 @@ namespace Content.Client.UserInterface
Control HandsContainer { get; }
Control SuspicionContainer { get; }
Control InventoryQuickButtonContainer { get; }
Control RightInventoryQuickButtonContainer { get; }
Control LeftInventoryQuickButtonContainer { get; }
bool CombatPanelVisible { get; set; }
bool CombatModeActive { get; set; }
@@ -100,7 +101,8 @@ namespace Content.Client.UserInterface
public Control HandsContainer { get; private set; }
public Control SuspicionContainer { get; private set; }
public Control InventoryQuickButtonContainer { get; private set; }
public Control RightInventoryQuickButtonContainer { get; private set; }
public Control LeftInventoryQuickButtonContainer { get; private set; }
public bool CombatPanelVisible
{
@@ -260,21 +262,6 @@ namespace Content.Client.UserInterface
_inputManager.SetInputCommand(ContentKeyFunctions.OpenTutorial,
InputCmdHandler.FromDelegate(s => ButtonTutorialOnOnToggled()));
var inventoryContainer = new HBoxContainer
{
SeparationOverride = 10
};
RootControl.AddChild(inventoryContainer);
LayoutContainer.SetGrowHorizontal(inventoryContainer, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetGrowVertical(inventoryContainer, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetAnchorAndMarginPreset(inventoryContainer, LayoutContainer.LayoutPreset.BottomRight);
InventoryQuickButtonContainer = new MarginContainer
{
SizeFlagsVertical = Control.SizeFlags.ShrinkEnd
};
_combatPanelContainer = new VBoxContainer
{
@@ -289,23 +276,40 @@ namespace Content.Client.UserInterface
}
};
LayoutContainer.SetGrowHorizontal(_combatPanelContainer, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetGrowVertical(_combatPanelContainer, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetAnchorAndMarginPreset(_combatPanelContainer, LayoutContainer.LayoutPreset.BottomRight);
LayoutContainer.SetMarginBottom(_combatPanelContainer, -10f);
RootControl.AddChild(_combatPanelContainer);
_combatModeButton.OnToggled += args => OnCombatModeChanged?.Invoke(args.Pressed);
_targetingDoll.OnZoneChanged += args => OnTargetingZoneChanged?.Invoke(args);
inventoryContainer.Children.Add(InventoryQuickButtonContainer);
inventoryContainer.Children.Add(_combatPanelContainer);
var centerBottomContainer = new HBoxContainer
{
SeparationOverride = 5
};
LayoutContainer.SetAnchorAndMarginPreset(centerBottomContainer, LayoutContainer.LayoutPreset.CenterBottom);
LayoutContainer.SetGrowHorizontal(centerBottomContainer, LayoutContainer.GrowDirection.Both);
LayoutContainer.SetGrowVertical(centerBottomContainer, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetMarginBottom(centerBottomContainer, -10f);
RootControl.AddChild(centerBottomContainer);
HandsContainer = new MarginContainer
{
SizeFlagsVertical = Control.SizeFlags.ShrinkEnd
};
RootControl.AddChild(HandsContainer);
LayoutContainer.SetAnchorAndMarginPreset(HandsContainer, LayoutContainer.LayoutPreset.CenterBottom);
LayoutContainer.SetGrowHorizontal(HandsContainer, LayoutContainer.GrowDirection.Both);
LayoutContainer.SetGrowVertical(HandsContainer, LayoutContainer.GrowDirection.Begin);
RightInventoryQuickButtonContainer = new MarginContainer
{
SizeFlagsVertical = Control.SizeFlags.ShrinkEnd
};
LeftInventoryQuickButtonContainer = new MarginContainer
{
SizeFlagsVertical = Control.SizeFlags.ShrinkEnd
};
centerBottomContainer.AddChild(LeftInventoryQuickButtonContainer);
centerBottomContainer.AddChild(HandsContainer);
centerBottomContainer.AddChild(RightInventoryQuickButtonContainer);
SuspicionContainer = new MarginContainer
{

View File

@@ -1,11 +1,15 @@
using Content.Shared.GameObjects.Components.Items;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Maths;
namespace Content.Client.UserInterface
{
public class HandButton : ItemSlotButton
{
private bool _activeHand;
private bool _highlighted;
public HandButton(Texture texture, Texture storageTexture, Texture blockedTexture, HandLocation location) : base(texture, storageTexture)
{
Location = location;
@@ -21,5 +25,23 @@ namespace Content.Client.UserInterface
public HandLocation Location { get; }
public TextureRect Blocked { get; }
public void SetActiveHand(bool active)
{
_activeHand = active;
UpdateHighlight();
}
public override void Highlight(bool highlight)
{
_highlighted = highlight;
UpdateHighlight();
}
private void UpdateHighlight()
{
// always stay highlighted if active
base.Highlight(_activeHand || _highlighted);
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Content.Client.GameObjects.Components.Items;
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects.Components.Items;
using Content.Shared.Input;
@@ -21,8 +22,6 @@ namespace Content.Client.UserInterface
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IItemSlotManager _itemSlotManager = default!;
private readonly TextureRect _activeHandRect;
private readonly Texture _leftHandTexture;
private readonly Texture _middleHandTexture;
private readonly Texture _rightHandTexture;
@@ -52,24 +51,14 @@ namespace Content.Client.UserInterface
Children =
{
(_topPanel = ItemStatusPanel.FromSide(HandLocation.Middle)),
(_handsContainer = new HBoxContainer {SeparationOverride = 0})
(_handsContainer = new HBoxContainer())
}
}),
(_leftPanel = ItemStatusPanel.FromSide(HandLocation.Left))
}
});
var textureHandActive = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_active.png");
// Active hand
_activeHandRect = new TextureRect
{
Texture = textureHandActive,
TextureScale = (2, 2)
};
_leftHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_l.png");
_middleHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_middle.png");
_middleHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_l.png");
_rightHandTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/hand_r.png");
}
@@ -119,13 +108,6 @@ namespace Content.Client.UserInterface
button.OnStoragePressed += args => _OnStoragePressed(args, slot);
_handsContainer.AddChild(button);
if (_activeHandRect.Parent == null)
{
button.AddChild(_activeHandRect);
_activeHandRect.SetPositionInParent(1);
}
hand.Button = button;
}
@@ -135,11 +117,6 @@ namespace Content.Client.UserInterface
if (button != null)
{
if (button.Children.Contains(_activeHandRect))
{
button.RemoveChild(_activeHandRect);
}
_handsContainer.RemoveChild(button);
}
}
@@ -186,14 +163,8 @@ namespace Content.Client.UserInterface
hand.Button!.Button.Texture = HandTexture(hand.Location);
hand.Button!.SetPositionInParent(i);
_itemSlotManager.SetItemSlot(hand.Button, hand.Entity);
}
_activeHandRect.Parent?.RemoveChild(_activeHandRect);
component.GetHand(component.ActiveIndex)?.Button?.AddChild(_activeHandRect);
if (hands.Length > 0)
{
_activeHandRect.SetPositionInParent(1);
hand.Button!.SetActiveHand(component.ActiveIndex == hand.Name);
}
_leftPanel.SetPositionFirst();

View File

@@ -1,4 +1,5 @@
using System;
using Content.Client.UserInterface.Stylesheets;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Shaders;
using Robust.Client.UserInterface;
@@ -26,11 +27,11 @@ namespace Content.Client.UserInterface
public bool EntityHover => HoverSpriteView.Sprite != null;
public bool MouseIsHovering = false;
private readonly ShaderInstance _highlightShader;
private readonly PanelContainer _highlightRect;
public ItemSlotButton(Texture texture, Texture storageTexture)
{
_highlightShader = IoCManager.Resolve<IPrototypeManager>().Index<ShaderPrototype>(HighlightShader).Instance();
CustomMinimumSize = (64, 64);
AddChild(Button = new TextureRect
@@ -40,6 +41,13 @@ namespace Content.Client.UserInterface
MouseFilter = MouseFilterMode.Stop
});
AddChild(_highlightRect = new PanelContainer
{
StyleClasses = { StyleNano.StyleClassHandSlotHighlight },
CustomMinimumSize = (32, 32),
Visible = false
});
Button.OnKeyBindDown += OnButtonPressed;
AddChild(SpriteView = new SpriteView
@@ -102,18 +110,16 @@ namespace Content.Client.UserInterface
}
}
public void Highlight(bool on)
public virtual void Highlight(bool highlight)
{
// I make no claim that this actually looks good but it's a start.
if (on)
if (highlight)
{
Button.ShaderOverride = _highlightShader;
_highlightRect.Visible = true;
}
else
{
Button.ShaderOverride = null;
_highlightRect.Visible = false;
}
}
private void OnButtonPressed(GUIBoundKeyEventArgs args)

View File

@@ -32,7 +32,7 @@ namespace Content.Client.UserInterface
[ViewVariables]
private IEntity? _entity;
public ItemStatusPanel(Texture texture, StyleBox.Margin margin)
public ItemStatusPanel(Texture texture, StyleBox.Margin cutout, StyleBox.Margin flat, Label.AlignMode textAlign)
{
var panel = new StyleBoxTexture
{
@@ -40,7 +40,8 @@ namespace Content.Client.UserInterface
};
panel.SetContentMarginOverride(StyleBox.Margin.Vertical, 4);
panel.SetContentMarginOverride(StyleBox.Margin.Horizontal, 6);
panel.SetPatchMargin(margin, 13);
panel.SetPatchMargin(flat, 2);
panel.SetPatchMargin(cutout, 13);
AddChild(_panel = new PanelContainer
{
@@ -57,7 +58,8 @@ namespace Content.Client.UserInterface
(_itemNameLabel = new Label
{
ClipText = true,
StyleClasses = {StyleNano.StyleClassItemStatus}
StyleClasses = {StyleNano.StyleClassItemStatus},
Align = textAlign
})
}
}
@@ -78,27 +80,35 @@ namespace Content.Client.UserInterface
public static ItemStatusPanel FromSide(HandLocation location)
{
string texture;
StyleBox.Margin margin;
StyleBox.Margin cutOut;
StyleBox.Margin flat;
Label.AlignMode textAlign;
switch (location)
{
case HandLocation.Left:
texture = "/Textures/Interface/Nano/item_status_right.svg.96dpi.png";
margin = StyleBox.Margin.Left | StyleBox.Margin.Top;
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_left.svg.96dpi.png";
margin = StyleBox.Margin.Right | StyleBox.Margin.Top;
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";
margin = StyleBox.Margin.Right | StyleBox.Margin.Top;
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);
}
return new ItemStatusPanel(ResC.GetTexture(texture), margin);
return new ItemStatusPanel(ResC.GetTexture(texture), cutOut, flat, textAlign);
}
public void Update(IEntity? entity)

View File

@@ -16,6 +16,8 @@ namespace Content.Client.UserInterface.Stylesheets
public sealed class StyleNano : StyleBase
{
public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel";
public const string StyleClassInventorySlotBackground = "InventorySlotBackground";
public const string StyleClassHandSlotHighlight = "HandSlotHighlight";
public const string StyleClassTransparentBorderedWindowPanel = "TransparentBorderedWindowPanel";
public const string StyleClassHotbarPanel = "HotbarPanel";
public const string StyleClassTooltipPanel = "tooltipBox";
@@ -103,6 +105,21 @@ namespace Content.Client.UserInterface.Stylesheets
};
borderedWindowBackground.SetPatchMargin(StyleBox.Margin.All, 2);
var invSlotBgTex = resCache.GetTexture("/Textures/Interface/Inventory/inv_slot_background.png");
var invSlotBg = new StyleBoxTexture
{
Texture = invSlotBgTex,
};
invSlotBg.SetPatchMargin(StyleBox.Margin.All, 2);
invSlotBg.SetContentMarginOverride(StyleBox.Margin.All, 0);
var handSlotHighlightTex = resCache.GetTexture("/Textures/Interface/Inventory/hand_slot_highlight.png");
var handSlotHighlight = new StyleBoxTexture
{
Texture = handSlotHighlightTex,
};
handSlotHighlight.SetPatchMargin(StyleBox.Margin.All, 2);
var borderedTransparentWindowBackgroundTex = resCache.GetTexture("/Textures/Interface/Nano/transparent_window_background_bordered.png");
var borderedTransparentWindowBackground = new StyleBoxTexture
{
@@ -385,6 +402,20 @@ namespace Content.Client.UserInterface.Stylesheets
{
new StyleProperty(PanelContainer.StylePropertyPanel, borderedTransparentWindowBackground),
}),
// inventory slot background
new StyleRule(
new SelectorElement(null, new[] {StyleClassInventorySlotBackground}, null, null),
new[]
{
new StyleProperty(PanelContainer.StylePropertyPanel, invSlotBg),
}),
// hand slot highlight
new StyleRule(
new SelectorElement(null, new[] {StyleClassHandSlotHighlight}, null, null),
new[]
{
new StyleProperty(PanelContainer.StylePropertyPanel, handSlotHighlight),
}),
// Hotbar background
new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {StyleClassHotbarPanel}, null, null),
new[]