Minimalist Action Bar (#21352)
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 _)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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))
|
||||||
{
|
|
||||||
for (var i = 0; i < page.Size; i++)
|
|
||||||
{
|
|
||||||
if (page[i] == actionId)
|
|
||||||
{
|
|
||||||
return;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user