Minimalist Action Bar (#21352)

This commit is contained in:
Nemanja
2023-11-13 22:27:14 -05:00
committed by GitHub
parent 2fdc566969
commit 4e84961ef8
12 changed files with 111 additions and 317 deletions

View File

@@ -80,11 +80,6 @@ namespace Content.Client.Input
common.AddFunction(boundKey); common.AddFunction(boundKey);
} }
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
{
common.AddFunction(boundKey);
}
var aghost = contexts.New("aghost", "common"); var aghost = contexts.New("aghost", "common");
aghost.AddFunction(EngineKeyFunctions.MoveUp); aghost.AddFunction(EngineKeyFunctions.MoveUp);
aghost.AddFunction(EngineKeyFunctions.MoveDown); aghost.AddFunction(EngineKeyFunctions.MoveDown);

View File

@@ -224,10 +224,6 @@ namespace Content.Client.Options.UI.Tabs
{ {
AddButton(boundKey); AddButton(boundKey);
} }
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
{
AddButton(boundKey);
}
AddHeader("ui-options-header-shuttle"); AddHeader("ui-options-header-shuttle");
AddButton(ContentKeyFunctions.ShuttleStrafeUp); AddButton(ContentKeyFunctions.ShuttleStrafeUp);

View File

@@ -22,10 +22,10 @@
<Control/> <Control/>
</BoxContainer> </BoxContainer>
<BoxContainer Name="VoteMenu" Access="Public" Margin="0 10 0 10" Orientation="Vertical"/> <BoxContainer Name="VoteMenu" Access="Public" Margin="0 10 0 10" Orientation="Vertical"/>
<actions:ActionsBar Name="Actions" Access="Protected" />
</BoxContainer> </BoxContainer>
<widgets:GhostGui Name="Ghost" Access="Protected" /> <widgets:GhostGui Name="Ghost" Access="Protected" />
<hotbar:HotbarGui Name="Hotbar" Access="Protected" /> <hotbar:HotbarGui Name="Hotbar" Access="Protected" />
<actions:ActionsBar Name="Actions" Access="Protected" />
<chat:ResizableChatBox Name="Chat" Access="Protected" /> <chat:ResizableChatBox Name="Chat" Access="Protected" />
<alerts:AlertsUI Name="Alerts" Access="Protected" /> <alerts:AlertsUI Name="Alerts" Access="Protected" />
</screens:DefaultGameScreen> </screens:DefaultGameScreen>

View File

@@ -17,7 +17,6 @@ public sealed partial class DefaultGameScreen : InGameScreen
SetAnchorPreset(MainViewport, LayoutPreset.Wide); SetAnchorPreset(MainViewport, LayoutPreset.Wide);
SetAnchorPreset(ViewportContainer, LayoutPreset.Wide); SetAnchorPreset(ViewportContainer, LayoutPreset.Wide);
SetAnchorAndMarginPreset(TopLeft, LayoutPreset.TopLeft, margin: 10); SetAnchorAndMarginPreset(TopLeft, LayoutPreset.TopLeft, margin: 10);
SetAnchorAndMarginPreset(Actions, LayoutPreset.BottomLeft, margin: 10);
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80); SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5); SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
SetAnchorAndMarginPreset(Chat, LayoutPreset.TopRight, margin: 10); SetAnchorAndMarginPreset(Chat, LayoutPreset.TopRight, margin: 10);
@@ -25,6 +24,7 @@ public sealed partial class DefaultGameScreen : InGameScreen
Chat.OnResized += ChatOnResized; Chat.OnResized += ChatOnResized;
Chat.OnChatResizeFinish += ChatOnResizeFinish; Chat.OnChatResizeFinish += ChatOnResizeFinish;
Actions.ActionsContainer.Columns = 1;
} }
private void ChatOnResizeFinish(Vector2 _) private void ChatOnResizeFinish(Vector2 _)

View File

@@ -19,7 +19,7 @@ public sealed partial class SeparatedChatGameScreen : InGameScreen
SetAnchorPreset(ViewportContainer, LayoutPreset.Wide); SetAnchorPreset(ViewportContainer, LayoutPreset.Wide);
SetAnchorPreset(MainViewport, LayoutPreset.Wide); SetAnchorPreset(MainViewport, LayoutPreset.Wide);
SetAnchorAndMarginPreset(VoteMenu, LayoutPreset.TopLeft, margin: 10); SetAnchorAndMarginPreset(VoteMenu, LayoutPreset.TopLeft, margin: 10);
SetAnchorAndMarginPreset(Actions, LayoutPreset.BottomLeft, margin: 10); SetAnchorAndMarginPreset(Actions, LayoutPreset.TopLeft, margin: 10);
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80); SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5); SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10); SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10);

View File

@@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Runtime.InteropServices;
using Content.Client.Actions; using Content.Client.Actions;
using Content.Client.Construction; using Content.Client.Construction;
using Content.Client.Gameplay; using Content.Client.Gameplay;
@@ -49,17 +48,14 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
[UISystemDependency] private readonly TargetOutlineSystem? _targetOutline = default; [UISystemDependency] private readonly TargetOutlineSystem? _targetOutline = default;
[UISystemDependency] private readonly SpriteSystem _spriteSystem = default!; [UISystemDependency] private readonly SpriteSystem _spriteSystem = default!;
private const int DefaultPageIndex = 0;
private ActionButtonContainer? _container; private ActionButtonContainer? _container;
private readonly List<ActionPage> _pages = new(); private readonly List<EntityUid?> _actions = new();
private int _currentPageIndex = DefaultPageIndex;
private readonly DragDropHelper<ActionButton> _menuDragHelper; private readonly DragDropHelper<ActionButton> _menuDragHelper;
private readonly TextureRect _dragShadow; private readonly TextureRect _dragShadow;
private ActionsWindow? _window; private ActionsWindow? _window;
private ActionsBar? ActionsBar => UIManager.GetActiveUIWidgetOrNull<ActionsBar>(); private ActionsBar? ActionsBar => UIManager.GetActiveUIWidgetOrNull<ActionsBar>();
private MenuButton? ActionButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.ActionButton; private MenuButton? ActionButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.ActionButton;
private ActionPage CurrentPage => _pages[_currentPageIndex];
public bool IsDragging => _menuDragHelper.IsDragging; public bool IsDragging => _menuDragHelper.IsDragging;
@@ -79,14 +75,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
SetSize = new Vector2(64, 64), SetSize = new Vector2(64, 64),
MouseFilter = MouseFilterMode.Ignore MouseFilter = MouseFilterMode.Ignore
}; };
var pageCount = ContentKeyFunctions.GetLoadoutBoundKeys().Length;
var buttonCount = ContentKeyFunctions.GetHotbarBoundKeys().Length;
for (var i = 0; i < pageCount; i++)
{
var page = new ActionPage(buttonCount);
_pages.Add(page);
}
} }
public override void Initialize() public override void Initialize()
@@ -139,15 +127,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
}, false, true)); }, false, true));
} }
var loadoutKeys = ContentKeyFunctions.GetLoadoutBoundKeys();
for (var i = 0; i < loadoutKeys.Length; i++)
{
var boundId = i; // This is needed, because the lambda captures it.
var boundKey = loadoutKeys[i];
builder = builder.Bind(boundKey,
InputCmdHandler.FromDelegate(_ => ChangePage(boundId)));
}
builder builder
.Bind(ContentKeyFunctions.OpenActionsMenu, .Bind(ContentKeyFunctions.OpenActionsMenu,
InputCmdHandler.FromDelegate(_ => ToggleWindow())) InputCmdHandler.FromDelegate(_ => ToggleWindow()))
@@ -178,7 +157,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (!_timing.IsFirstTimePredicted || _actionsSystem == null || SelectingTargetFor is not { } actionId) if (!_timing.IsFirstTimePredicted || _actionsSystem == null || SelectingTargetFor is not { } actionId)
return false; return false;
if (_playerManager.LocalPlayer?.ControlledEntity is not { } user) if (_playerManager.LocalEntity is not { } user)
return false; return false;
if (!EntityManager.TryGetComponent(user, out ActionsComponent? comp)) if (!EntityManager.TryGetComponent(user, out ActionsComponent? comp))
@@ -332,76 +311,16 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
private void TriggerAction(int index) private void TriggerAction(int index)
{ {
if (_actionsSystem == null || if (_actionsSystem == null ||
CurrentPage[index] is not { } actionId || !_actions.TryGetValue(index, out var actionId) ||
!_actionsSystem.TryGetActionData(actionId, out var baseAction)) !_actionsSystem.TryGetActionData(actionId, out var baseAction))
{ {
return; return;
} }
if (baseAction is BaseTargetActionComponent action) if (baseAction is BaseTargetActionComponent action)
ToggleTargeting(actionId, action); ToggleTargeting(actionId.Value, action);
else else
_actionsSystem?.TriggerAction(actionId, baseAction); _actionsSystem?.TriggerAction(actionId.Value, baseAction);
}
private void ChangePage(int index)
{
if (_actionsSystem == null)
return;
var lastPage = _pages.Count - 1;
if (index < 0)
{
index = lastPage;
}
else if (index > lastPage)
{
index = 0;
}
_currentPageIndex = index;
var page = _pages[_currentPageIndex];
_container?.SetActionData(_actionsSystem, page);
ActionsBar!.PageButtons.Label.Text = $"{_currentPageIndex + 1}";
}
private void OnLeftArrowPressed(ButtonEventArgs args)
{
ChangePage(_currentPageIndex - 1);
}
private void OnRightArrowPressed(ButtonEventArgs args)
{
ChangePage(_currentPageIndex + 1);
}
private void AppendAction(EntityUid action)
{
if (_container == null)
return;
foreach (var button in _container.GetButtons())
{
if (button.ActionId != null)
continue;
SetAction(button, action);
return;
}
foreach (var page in _pages)
{
for (var i = 0; i < page.Size; i++)
{
var pageAction = page[i];
if (pageAction != null)
continue;
page[i] = action;
return;
}
}
} }
private void OnActionAdded(EntityUid actionId) private void OnActionAdded(EntityUid actionId)
@@ -416,18 +335,10 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (action is BaseTargetActionComponent targetAction && action.Toggled) if (action is BaseTargetActionComponent targetAction && action.Toggled)
StartTargeting(actionId, targetAction); StartTargeting(actionId, targetAction);
foreach (var page in _pages) if (_actions.Contains(actionId))
{ return;
for (var i = 0; i < page.Size; i++)
{
if (page[i] == actionId)
{
return;
}
}
}
AppendAction(actionId); _actions.Add(actionId);
} }
private void OnActionRemoved(EntityUid actionId) private void OnActionRemoved(EntityUid actionId)
@@ -435,40 +346,18 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (_container == null) if (_container == null)
return; return;
// stop targeting if the action is removed
if (actionId == SelectingTargetFor) if (actionId == SelectingTargetFor)
StopTargeting(); StopTargeting();
foreach (var button in _container.GetButtons()) _actions.RemoveAll(x => x == actionId);
{
if (button.ActionId == actionId)
{
SetAction(button, null);
}
}
foreach (var page in _pages)
{
for (var i = 0; i < page.Size; i++)
{
if (page[i] == actionId)
{
page[i] = null;
}
}
}
} }
private void OnActionsUpdated() private void OnActionsUpdated()
{ {
QueueWindowUpdate(); QueueWindowUpdate();
if (_container == null)
return;
foreach (var button in _container.GetButtons()) if (_actionsSystem != null)
{ _container?.SetActionData(_actionsSystem, _actions.ToArray());
button.UpdateIcons();
}
} }
private void ActionButtonPressed(ButtonEventArgs args) private void ActionButtonPressed(ButtonEventArgs args)
@@ -512,8 +401,8 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
return filter switch return filter switch
{ {
Filters.Enabled => action.Enabled, Filters.Enabled => action.Enabled,
Filters.Item => action.Container != null && action.Container != _playerManager.LocalPlayer?.ControlledEntity, Filters.Item => action.Container != null && action.Container != _playerManager.LocalEntity,
Filters.Innate => action.Container == null || action.Container == _playerManager.LocalPlayer?.ControlledEntity, Filters.Innate => action.Container == null || action.Container == _playerManager.LocalEntity,
Filters.Instant => action is InstantActionComponent, Filters.Instant => action is InstantActionComponent,
Filters.Targeted => action is BaseTargetActionComponent, Filters.Targeted => action is BaseTargetActionComponent,
_ => throw new ArgumentOutOfRangeException(nameof(filter), filter, null) _ => throw new ArgumentOutOfRangeException(nameof(filter), filter, null)
@@ -580,7 +469,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (_actionsSystem == null) if (_actionsSystem == null)
return; return;
if (_playerManager.LocalPlayer?.ControlledEntity is not { } player) if (_playerManager.LocalEntity is not { } player)
return; return;
var search = _window.SearchBar.Text; var search = _window.SearchBar.Text;
@@ -615,7 +504,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
PopulateActions(actions); PopulateActions(actions);
} }
private void SetAction(ActionButton button, EntityUid? actionId) private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlots = true)
{ {
if (_actionsSystem == null) if (_actionsSystem == null)
return; return;
@@ -627,22 +516,30 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
button.ClearData(); button.ClearData();
if (_container?.TryGetButtonIndex(button, out position) ?? false) if (_container?.TryGetButtonIndex(button, out position) ?? false)
{ {
CurrentPage[position] = actionId; _actions.RemoveAt(position);
} }
return;
} }
else if (button.TryReplaceWith(actionId.Value, _actionsSystem) &&
if (button.TryReplaceWith(actionId.Value, _actionsSystem) &&
_container != null && _container != null &&
_container.TryGetButtonIndex(button, out position)) _container.TryGetButtonIndex(button, out position))
{ {
CurrentPage[position] = actionId; if (position >= _actions.Count)
{
_actions.Add(actionId);
}
else
{
_actions[position] = actionId;
}
} }
if (updateSlots)
_container?.SetActionData(_actionsSystem, _actions.ToArray());
} }
private void DragAction() private void DragAction()
{ {
EntityUid? swapAction = null;
if (UIManager.CurrentlyHovered is ActionButton button) if (UIManager.CurrentlyHovered is ActionButton button)
{ {
if (!_menuDragHelper.IsDragging || _menuDragHelper.Dragged?.ActionId is not { } type) if (!_menuDragHelper.IsDragging || _menuDragHelper.Dragged?.ActionId is not { } type)
@@ -651,14 +548,18 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
return; return;
} }
SetAction(button, type); swapAction = button.ActionId;
SetAction(button, type, false);
} }
if (_menuDragHelper.Dragged is {Parent: ActionButtonContainer} old) if (_menuDragHelper.Dragged is {Parent: ActionButtonContainer} old)
{ {
SetAction(old, null); SetAction(old, swapAction, false);
} }
if (_actionsSystem != null)
_container?.SetActionData(_actionsSystem, _actions.ToArray());
_menuDragHelper.EndDrag(); _menuDragHelper.EndDrag();
} }
@@ -737,6 +638,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (args.Function != EngineKeyFunctions.UIClick || _actionsSystem == null) if (args.Function != EngineKeyFunctions.UIClick || _actionsSystem == null)
return; return;
//todo: make dragging onto the same spot NOT trigger again
if (UIManager.CurrentlyHovered == button) if (UIManager.CurrentlyHovered == button)
{ {
_menuDragHelper.EndDrag(); _menuDragHelper.EndDrag();
@@ -813,9 +715,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
return; return;
} }
ActionsBar.PageButtons.LeftArrow.OnPressed -= OnLeftArrowPressed;
ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed;
if (_window != null) if (_window != null)
{ {
_window.OnOpen -= OnWindowOpened; _window.OnOpen -= OnWindowOpened;
@@ -846,9 +745,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
return; return;
} }
ActionsBar.PageButtons.LeftArrow.OnPressed += OnLeftArrowPressed;
ActionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed;
RegisterActionContainer(ActionsBar.ActionsContainer); RegisterActionContainer(ActionsBar.ActionsContainer);
_actionsSystem?.LinkAllActions(); _actionsSystem?.LinkAllActions();
@@ -856,12 +752,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
public void RegisterActionContainer(ActionButtonContainer container) public void RegisterActionContainer(ActionButtonContainer container)
{ {
if (_container != null)
{
_container.ActionPressed -= OnActionPressed;
_container.ActionUnpressed -= OnActionPressed;
}
_container = container; _container = container;
_container.ActionPressed += OnActionPressed; _container.ActionPressed += OnActionPressed;
_container.ActionUnpressed += OnActionUnpressed; _container.ActionUnpressed += OnActionUnpressed;
@@ -877,12 +767,12 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (_actionsSystem == null) if (_actionsSystem == null)
return; return;
foreach (ref var assignment in CollectionsMarshal.AsSpan(assignments)) for (var i = 0; i < assignments.Count; i++)
{ {
_pages[assignment.Hotbar][assignment.Slot] = assignment.ActionId; _actions[i] = assignments[i].ActionId;
} }
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); _container?.SetActionData(_actionsSystem, _actions.ToArray());
} }
public void RemoveActionContainer() public void RemoveActionContainer()
@@ -918,8 +808,8 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (_actionsSystem == null) if (_actionsSystem == null)
return; return;
LoadDefaultActions(component); LoadDefaultActions();
_container?.SetActionData(_actionsSystem, _pages[DefaultPageIndex]); _container?.SetActionData(_actionsSystem, _actions.ToArray());
QueueWindowUpdate(); QueueWindowUpdate();
} }
@@ -930,7 +820,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
StopTargeting(); StopTargeting();
} }
private void LoadDefaultActions(ActionsComponent component) private void LoadDefaultActions()
{ {
if (_actionsSystem == null) if (_actionsSystem == null)
return; return;
@@ -938,36 +828,11 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
var actions = _actionsSystem.GetClientActions().Where(action => action.Comp.AutoPopulate).ToList(); var actions = _actionsSystem.GetClientActions().Where(action => action.Comp.AutoPopulate).ToList();
actions.Sort(ActionComparer); actions.Sort(ActionComparer);
var offset = 0; _actions.Clear();
var totalPages = _pages.Count; foreach (var (action, _) in actions)
var pagesLeft = totalPages;
var currentPage = DefaultPageIndex;
while (pagesLeft > 0)
{ {
var page = _pages[currentPage]; if (!_actions.Contains(action))
var pageSize = page.Size; _actions.Add(action);
for (var slot = 0; slot < pageSize; slot++)
{
var actionIndex = slot + offset;
if (actionIndex < actions.Count)
{
page[slot] = actions[slot + offset].Id;
}
else
{
page[slot] = null;
}
}
offset += pageSize;
currentPage++;
if (currentPage == totalPages)
{
currentPage = 0;
}
pagesLeft--;
} }
} }
@@ -1078,34 +943,4 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
handOverlay.IconOverride = null; handOverlay.IconOverride = null;
handOverlay.EntityOverride = null; handOverlay.EntityOverride = null;
} }
//TODO: Serialize this shit
private sealed class ActionPage
{
private readonly EntityUid?[] _data;
public ActionPage(int size)
{
_data = new EntityUid?[size];
}
public EntityUid? this[int index]
{
get => _data[index];
set => _data[index] = value;
}
public static implicit operator EntityUid?[](ActionPage p)
{
return p._data.ToArray();
}
public void Clear()
{
Array.Fill(_data, null);
}
public int Size => _data.Length;
}
} }

View File

@@ -49,6 +49,8 @@ public sealed class ActionButton : Control, IEntityControl
private readonly SpriteView _smallItemSpriteView; private readonly SpriteView _smallItemSpriteView;
private readonly SpriteView _bigItemSpriteView; private readonly SpriteView _bigItemSpriteView;
private Texture? _buttonBackgroundTexture;
public EntityUid? ActionId { get; private set; } public EntityUid? ActionId { get; private set; }
private BaseActionComponent? _action; private BaseActionComponent? _action;
public bool Locked { get; set; } public bool Locked { get; set; }
@@ -138,9 +140,9 @@ public sealed class ActionButton : Control, IEntityControl
}); });
Cooldown = new CooldownGraphic {Visible = false}; Cooldown = new CooldownGraphic {Visible = false};
AddChild(Button);
AddChild(_bigActionIcon); AddChild(_bigActionIcon);
AddChild(_bigItemSpriteView); AddChild(_bigItemSpriteView);
AddChild(Button);
AddChild(HighlightRect); AddChild(HighlightRect);
AddChild(Label); AddChild(Label);
AddChild(Cooldown); AddChild(Cooldown);
@@ -167,7 +169,7 @@ public sealed class ActionButton : Control, IEntityControl
protected override void OnThemeUpdated() protected override void OnThemeUpdated()
{ {
base.OnThemeUpdated(); base.OnThemeUpdated();
Button.Texture = Theme.ResolveTexture("SlotBackground"); _buttonBackgroundTexture = Theme.ResolveTexture("SlotBackground");
Label.FontColorOverride = Theme.ResolveColorOrSpecified("whiteText"); Label.FontColorOverride = Theme.ResolveColorOrSpecified("whiteText");
} }
@@ -263,6 +265,7 @@ public sealed class ActionButton : Control, IEntityControl
public void UpdateIcons() public void UpdateIcons()
{ {
UpdateItemIcon(); UpdateItemIcon();
UpdateBackground();
if (_action == null) if (_action == null)
{ {
@@ -278,6 +281,18 @@ public sealed class ActionButton : Control, IEntityControl
SetActionIcon(_action.Icon != null ? _spriteSys.Frame0(_action.Icon) : null); SetActionIcon(_action.Icon != null ? _spriteSys.Frame0(_action.Icon) : null);
} }
public void UpdateBackground()
{
if (_action == null)
{
Button.Texture = null;
}
else
{
Button.Texture = _buttonBackgroundTexture;
}
}
public bool TryReplaceWith(EntityUid actionId, ActionsSystem system) public bool TryReplaceWith(EntityUid actionId, ActionsSystem system)
{ {
if (Locked) if (Locked)
@@ -363,7 +378,8 @@ public sealed class ActionButton : Control, IEntityControl
public void DrawModeChanged() public void DrawModeChanged()
{ {
HighlightRect.Visible = _beingHovered; _controller ??= UserInterfaceManager.GetUIController<ActionUIController>();
HighlightRect.Visible = _beingHovered && (_action != null || _controller.IsDragging);
// always show the normal empty button style if no action in this slot // always show the normal empty button style if no action in this slot
if (_action == null) if (_action == null)
@@ -373,8 +389,7 @@ public sealed class ActionButton : Control, IEntityControl
} }
// show a hover only if the action is usable or another action is being dragged on top of this // show a hover only if the action is usable or another action is being dragged on top of this
_controller ??= UserInterfaceManager.GetUIController<ActionUIController>(); if (_beingHovered && (_controller.IsDragging || _action!.Enabled))
if (_beingHovered && (_controller.IsDragging || _action.Enabled))
{ {
SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassHover); SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassHover);
} }

View File

@@ -1,12 +1,19 @@
using System.Linq;
using Content.Client.Actions; using Content.Client.Actions;
using Content.Shared.Input;
using Robust.Client.Input;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Utility;
namespace Content.Client.UserInterface.Systems.Actions.Controls; namespace Content.Client.UserInterface.Systems.Actions.Controls;
[Virtual] [Virtual]
public class ActionButtonContainer : GridContainer public class ActionButtonContainer : GridContainer
{ {
[Dependency] private readonly IEntityManager _entity = default!;
[Dependency] private readonly IInputManager _input = default!;
public event Action<GUIBoundKeyEventArgs, ActionButton>? ActionPressed; public event Action<GUIBoundKeyEventArgs, ActionButton>? ActionPressed;
public event Action<GUIBoundKeyEventArgs, ActionButton>? ActionUnpressed; public event Action<GUIBoundKeyEventArgs, ActionButton>? ActionUnpressed;
public event Action<ActionButton>? ActionFocusExited; public event Action<ActionButton>? ActionFocusExited;
@@ -14,7 +21,6 @@ public class ActionButtonContainer : GridContainer
public ActionButtonContainer() public ActionButtonContainer()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
UserInterfaceManager.GetUIController<ActionUIController>().RegisterActionContainer(this);
} }
public ActionButton this[int index] public ActionButton this[int index]
@@ -22,17 +28,42 @@ public class ActionButtonContainer : GridContainer
get => (ActionButton) GetChild(index); get => (ActionButton) GetChild(index);
} }
private void BuildActionButtons(int count)
{
var keys = ContentKeyFunctions.GetHotbarBoundKeys();
Children.Clear();
for (var index = 0; index < count; index++)
{
Children.Add(MakeButton(index));
}
ActionButton MakeButton(int index)
{
var button = new ActionButton(_entity);
if (keys.TryGetValue(index, out var boundKey))
{
button.KeyBind = boundKey;
var binding = _input.GetKeyBinding(boundKey);
button.Label.Text = binding.GetKeyString();
}
return button;
}
}
public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes)
{ {
ClearActionData(); var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1);
BuildActionButtons(uniqueCount);
for (var i = 0; i < actionTypes.Length; i++) for (var i = 0; i < uniqueCount; i++)
{ {
var action = actionTypes[i]; if (!actionTypes.TryGetValue(i, out var action))
if (action == null) action = null;
continue; ((ActionButton) GetChild(i)).UpdateData(action, system);
((ActionButton) GetChild(i)).UpdateData(action.Value, system);
} }
} }

View File

@@ -13,7 +13,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
MaxSize="64 9999" MaxSize="64 9999"
Name="ActionsContainer" Name="ActionsContainer"
Access="Public"/> Access="Public"
<controls:ActionPageButtons Name="PageButtons" Access="Public"/> Rows="1"/>
</BoxContainer> </BoxContainer>
</widgets:ActionsBar> </widgets:ActionsBar>

View File

@@ -1,6 +1,4 @@
using Content.Client.UserInterface.Systems.Actions.Controls; using Robust.Client.AutoGenerated;
using Content.Shared.Input;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
@@ -9,28 +7,9 @@ namespace Content.Client.UserInterface.Systems.Actions.Widgets;
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class ActionsBar : UIWidget public sealed partial class ActionsBar : UIWidget
{ {
[Dependency] private readonly IEntityManager _entity = default!;
public ActionsBar() public ActionsBar()
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
var keys = ContentKeyFunctions.GetHotbarBoundKeys();
for (var index = 1; index < keys.Length; index++)
{
ActionsContainer.Children.Add(MakeButton(index));
}
ActionsContainer.Children.Add(MakeButton(0));
ActionButton MakeButton(int index)
{
var boundKey = keys[index];
var button = new ActionButton(_entity);
button.KeyBind = boundKey;
button.Label.Text = index.ToString();
return button;
}
} }
} }

View File

@@ -84,23 +84,6 @@ namespace Content.Shared.Input
Hotbar1, Hotbar2, Hotbar3, Hotbar4, Hotbar5, Hotbar6, Hotbar7, Hotbar8, Hotbar9, Hotbar0 Hotbar1, Hotbar2, Hotbar3, Hotbar4, Hotbar5, Hotbar6, Hotbar7, Hotbar8, Hotbar9, Hotbar0
}; };
public static readonly BoundKeyFunction Loadout0 = "Loadout0";
public static readonly BoundKeyFunction Loadout1 = "Loadout1";
public static readonly BoundKeyFunction Loadout2 = "Loadout2";
public static readonly BoundKeyFunction Loadout3 = "Loadout3";
public static readonly BoundKeyFunction Loadout4 = "Loadout4";
public static readonly BoundKeyFunction Loadout5 = "Loadout5";
public static readonly BoundKeyFunction Loadout6 = "Loadout6";
public static readonly BoundKeyFunction Loadout7 = "Loadout7";
public static readonly BoundKeyFunction Loadout8 = "Loadout8";
public static readonly BoundKeyFunction Loadout9 = "Loadout9";
public static BoundKeyFunction[] GetLoadoutBoundKeys() =>
new[]
{
Loadout1, Loadout2, Loadout3, Loadout4, Loadout5, Loadout6, Loadout7, Loadout8, Loadout9, Loadout0
};
public static readonly BoundKeyFunction Vote0 = "Vote0"; public static readonly BoundKeyFunction Vote0 = "Vote0";
public static readonly BoundKeyFunction Vote1 = "Vote1"; public static readonly BoundKeyFunction Vote1 = "Vote1";
public static readonly BoundKeyFunction Vote2 = "Vote2"; public static readonly BoundKeyFunction Vote2 = "Vote2";

View File

@@ -510,43 +510,3 @@ binds:
- function: Hotbar9 - function: Hotbar9
type: State type: State
key: Num9 key: Num9
- function: Loadout0
type: State
key: Num0
mod1: Shift
- function: Loadout1
type: State
key: Num1
mod1: Shift
- function: Loadout2
type: State
key: Num2
mod1: Shift
- function: Loadout3
type: State
key: Num3
mod1: Shift
- function: Loadout4
type: State
key: Num4
mod1: Shift
- function: Loadout5
type: State
key: Num5
mod1: Shift
- function: Loadout6
type: State
key: Num6
mod1: Shift
- function: Loadout7
type: State
key: Num7
mod1: Shift
- function: Loadout8
type: State
key: Num8
mod1: Shift
- function: Loadout9
type: State
key: Num9
mod1: Shift