* attempt at moving MainViewport to UIWidget

* oldchat (prototype)

* separate oldchat and default ss14 HUD into their own files

* restores original default game screen logic and adds that logic into separated chat game screen

* hand reloading, several tweaks to port oldchat to main ss14 branch

oldchat is currently not selectable

* screen type cvar, gameplay state screen reloading/loading

* reload screen on ui layout cvar change

* fixes up basic reloading (HUD switching is still very bad)

* some UI widget reloading for main UI screen switching

* alert sync on screen change

* inventory reload

* hotbar margin fix

* chat bubbles above viewport

* whoops

* fixes ordering of speech bubble root

* should fix the chat focus issue (at least in-game, not lobby yet)

* should fix up the lobby/game chat focus

* fixes chat for lobby, turns lobby into a UI state

* viewport UI controller

* viewport ratio selection

* whoops

* adds the /tg/ widescreen ratio

* removes warning from inventory UI controller, adds background to separated chat game screen's chat portion

* menu button reload

* unload menu buttons only from gameplay state shutdown

* bugfix

* character button fix

* adds config options for viewport width/UI layout

* variable naming changes, get or null instead of get to avoid exceptions

* moves entity system get into controller
This commit is contained in:
Flipp Syder
2022-10-17 15:13:41 -07:00
committed by GitHub
parent 730eddf0ab
commit a3dafd88dc
37 changed files with 910 additions and 208 deletions

View File

@@ -52,7 +52,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
private ActionsWindow? _window;
private ActionsBar? _actionsBar;
private MenuButton? _actionButton;
private MenuButton? ActionButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.ActionButton;
private ActionPage CurrentPage => _pages[_currentPageIndex];
public bool IsDragging => _menuDragHelper.IsDragging;
@@ -88,7 +88,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
DebugTools.Assert(_window == null);
_window = UIManager.CreateWindow<ActionsWindow>();
_actionButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().ActionButton;
_actionsBar = UIManager.GetActiveUIWidget<ActionsBar>();
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop);
@@ -97,7 +96,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_window.ClearButton.OnPressed += OnClearPressed;
_window.SearchBar.OnTextChanged += OnSearchChanged;
_window.FilterButton.OnItemSelected += OnFilterSelected;
_actionButton.OnPressed += ActionButtonPressed;
_actionsBar.PageButtons.LeftArrow.OnPressed += OnLeftArrowPressed;
_actionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed;
@@ -146,16 +144,36 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
.Register<ActionUIController>();
}
public void UnloadButton()
{
if (ActionButton == null)
{
return;
}
ActionButton.OnPressed -= ActionButtonPressed;
}
public void LoadButton()
{
if (ActionButton == null)
{
return;
}
ActionButton.OnPressed += ActionButtonPressed;
}
private void OnWindowOpened()
{
if (_actionButton != null)
_actionButton.Pressed = true;
if (ActionButton != null)
ActionButton.Pressed = true;
}
private void OnWindowClosed()
{
if (_actionButton != null)
_actionButton.Pressed = false;
if (ActionButton != null)
ActionButton.Pressed = false;
}
public void OnStateExited(GameplayState state)
@@ -186,12 +204,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_actionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed;
}
if (_actionButton != null)
{
_actionButton.OnPressed -= ActionButtonPressed;
_actionButton.Pressed = false;
}
CommandBinds.Unregister<ActionUIController>();
}
@@ -607,12 +619,37 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_dragShadow.Visible = false;
}
public void ReloadActionContainer()
{
RegisterActionContainer();
}
public void RegisterActionContainer()
{
if (UIManager.ActiveScreen == null)
{
return;
}
var widget = UIManager.ActiveScreen.GetWidget<ActionsBar>();
if (widget == null)
{
return;
}
_actionsSystem?.UnlinkAllActions();
RegisterActionContainer(widget.ActionsContainer);
_actionsSystem?.LinkAllActions();
}
public void RegisterActionContainer(ActionButtonContainer container)
{
if (_container != null)
{
Logger.Warning("Action container already defined for UI controller");
return;
_container.ActionPressed -= OnActionPressed;
_container.ActionUnpressed -= OnActionPressed;
}
_container = container;

View File

@@ -30,14 +30,13 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
[UISystemDependency] private readonly VerbSystem _verbs = default!;
private AdminMenuWindow? _window;
private MenuButton? _adminButton;
private MenuButton? AdminButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.AdminButton;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_window == null);
_window = UIManager.CreateWindow<AdminMenuWindow>();
_adminButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().AdminButton;
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.Center);
_window.PlayerTabControl.OnEntryPressed += PlayerTabEntryPressed;
@@ -45,7 +44,6 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
_window.OnOpen += OnWindowOpen;
_window.OnClose += OnWindowClosed;
_admin.AdminStatusUpdated += AdminStatusUpdated;
_adminButton.OnPressed += AdminButtonPressed;
_input.SetInputCommand(ContentKeyFunctions.OpenAdminMenu,
InputCmdHandler.FromDelegate(_ => Toggle()));
@@ -53,16 +51,36 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
AdminStatusUpdated();
}
public void UnloadButton()
{
if (AdminButton == null)
{
return;
}
AdminButton.OnPressed -= AdminButtonPressed;
}
public void LoadButton()
{
if (AdminButton == null)
{
return;
}
AdminButton.OnPressed += AdminButtonPressed;
}
private void OnWindowOpen()
{
if (_adminButton != null)
_adminButton.Pressed = true;
if (AdminButton != null)
AdminButton.Pressed = true;
}
private void OnWindowClosed()
{
if (_adminButton != null)
_adminButton.Pressed = false;
if (AdminButton != null)
AdminButton.Pressed = false;
}
public void OnStateExited(GameplayState state)
@@ -80,19 +98,12 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
_admin.AdminStatusUpdated -= AdminStatusUpdated;
if (_adminButton != null)
{
_adminButton.Pressed = false;
_adminButton.OnPressed -= AdminButtonPressed;
_adminButton = null;
}
CommandBinds.Unregister<AdminUIController>();
}
private void AdminStatusUpdated()
{
_adminButton!.Visible = _conGroups.CanAdminMenu();
AdminButton!.Visible = _conGroups.CanAdminMenu();
}
private void AdminButtonPressed(ButtonEventArgs args)

View File

@@ -49,6 +49,11 @@ public sealed class AlertsUIController : UIController, IOnStateEntered<GameplayS
}
// initially populate the frame if system is available
SyncAlerts();
}
public void SyncAlerts()
{
var alerts = _alertsSystem?.ActiveAlerts;
if (alerts != null)
{

View File

@@ -29,14 +29,12 @@ public sealed class AHelpUIController: UIController, IOnStateChanged<GameplaySta
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IClyde _clyde = default!;
private BwoinkSystem? _bwoinkSystem;
private MenuButton? _ahelpButton;
private MenuButton? AhelpButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.AHelpButton;
private IAHelpUIHandler? _uiHelper;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_uiHelper == null);
_ahelpButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().AHelpButton;
_ahelpButton.OnPressed += AHelpButtonPressed;
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
CommandBinds.Builder
@@ -45,6 +43,26 @@ public sealed class AHelpUIController: UIController, IOnStateChanged<GameplaySta
.Register<AHelpUIController>();
}
public void UnloadButton()
{
if (AhelpButton == null)
{
return;
}
AhelpButton.OnPressed -= AHelpButtonPressed;
}
public void LoadButton()
{
if (AhelpButton == null)
{
return;
}
AhelpButton.OnPressed += AHelpButtonPressed;
}
private void OnAdminStatusUpdated()
{
if (_uiHelper is not { IsOpen: true })
@@ -60,9 +78,7 @@ public sealed class AHelpUIController: UIController, IOnStateChanged<GameplaySta
public void OnStateExited(GameplayState state)
{
DebugTools.Assert(_ahelpButton != null);
SetAHelpPressed(false);
_ahelpButton!.OnPressed -= AHelpButtonPressed;
_adminManager.AdminStatusUpdated -= OnAdminStatusUpdated;
_uiHelper?.Dispose();
_uiHelper = null;
@@ -83,10 +99,10 @@ public sealed class AHelpUIController: UIController, IOnStateChanged<GameplaySta
private void SetAHelpPressed(bool pressed)
{
if (_ahelpButton == null || _ahelpButton.Pressed == pressed)
if (AhelpButton == null || AhelpButton.Pressed == pressed)
return;
_ahelpButton.StyleClasses.Remove(MenuButton.StyleClassRedTopButton);
_ahelpButton.Pressed = pressed;
AhelpButton.StyleClasses.Remove(MenuButton.StyleClassRedTopButton);
AhelpButton.Pressed = pressed;
}
private void RecievedBwoink(object? sender, SharedBwoinkSystem.BwoinkTextMessage message)
@@ -106,7 +122,7 @@ public sealed class AHelpUIController: UIController, IOnStateChanged<GameplaySta
EnsureUIHelper();
if (!_uiHelper!.IsOpen)
{
_ahelpButton?.StyleClasses.Add(MenuButton.StyleClassRedTopButton);
AhelpButton?.StyleClasses.Add(MenuButton.StyleClassRedTopButton);
}
_uiHelper!.Receive(message);
}

View File

@@ -23,19 +23,16 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
private CharacterWindow? _window;
private MenuButton? _characterButton;
private MenuButton? CharacterButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.CharacterButton;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_window == null);
_characterButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().CharacterButton;
_characterButton.OnPressed += CharacterButtonPressed;
_window = UIManager.CreateWindow<CharacterWindow>();
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop);
_window.OnClose += () => { _characterButton.Pressed = false; };
_window.OnOpen += () => { _characterButton.Pressed = true; };
CommandBinds.Builder
.Bind(ContentKeyFunctions.OpenCharacterMenu,
@@ -51,13 +48,6 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
_window = null;
}
if (_characterButton != null)
{
_characterButton.OnPressed -= CharacterButtonPressed;
_characterButton.Pressed = false;
_characterButton = null;
}
CommandBinds.Unregister<CharacterUIController>();
}
@@ -73,6 +63,37 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
system.OnCharacterDetached -= CharacterDetached;
}
public void UnloadButton()
{
if (CharacterButton == null)
{
return;
}
CharacterButton.OnPressed -= CharacterButtonPressed;
}
public void LoadButton()
{
if (CharacterButton == null)
{
return;
}
CharacterButton.OnPressed += CharacterButtonPressed;
if (_window == null)
{
return;
}
_window.OnClose += DeactivateButton;
_window.OnOpen += ActivateButton;
}
private void DeactivateButton() => CharacterButton!.Pressed = false;
private void ActivateButton() => CharacterButton!.Pressed = true;
private void CharacterUpdated(CharacterData data)
{
if (_window == null)
@@ -141,6 +162,12 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
{
if (_window == null)
return;
if (CharacterButton != null)
{
CharacterButton.Pressed = !_window.IsOpen;
}
if (_window.IsOpen)
{
CloseWindow();

View File

@@ -186,6 +186,22 @@ public sealed class ChatUIController : UIController
InputCmdHandler.FromDelegate(_ => CycleChatChannel(false)));
}
public void SetMainChat(bool setting)
{
// This isn't very nice to look at.
var widget = UIManager.ActiveScreen?.GetWidget<ChatBox>();
if (widget == null)
{
widget = UIManager.ActiveScreen?.GetWidget<ResizableChatBox>();
if (widget == null)
{
return;
}
}
widget.Main = setting;
}
private void FocusChat()
{
foreach (var chat in _chats)
@@ -230,13 +246,13 @@ public sealed class ChatUIController : UIController
}
UpdateChannelPermissions();
}
if (_speechBubbleRoot.Parent == UIManager.StateRoot)
return;
public void SetSpeechBubbleRoot(LayoutContainer root)
{
_speechBubbleRoot.Orphan();
root.AddChild(_speechBubbleRoot);
LayoutContainer.SetAnchorPreset(_speechBubbleRoot, LayoutContainer.LayoutPreset.Wide);
UIManager.StateRoot.AddChild(_speechBubbleRoot);
_speechBubbleRoot.SetPositionLast();
}
@@ -701,6 +717,11 @@ public sealed class ChatUIController : UIController
return MapLocalIfGhost(PreferredChannel);
}
public void NotifyChatTextChange()
{
_typingIndicator?.ClientChangedChatText();
}
private readonly record struct SpeechBubbleData(string Message, SpeechBubble.SpeechType Type);
private sealed class SpeechBubbleQueueData

View File

@@ -4,15 +4,17 @@
xmlns:widgets="clr-namespace:Content.Client.UserInterface.Systems.Chat.Widgets"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Systems.Chat.Controls"
MouseFilter="Stop"
HorizontalExpand="True"
VerticalExpand="True"
MinSize="465 225">
<PanelContainer>
<PanelContainer HorizontalExpand="True" VerticalExpand="True">
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BackgroundColor="#25252AAA" />
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Vertical" SeparationOverride="4">
<OutputPanel Name="Contents" VerticalExpand="True" />
<controls:ChatInputBox Name="ChatInput" Access="Public" Margin="2"/>
<BoxContainer Orientation="Vertical" SeparationOverride="4" HorizontalExpand="True" VerticalExpand="True">
<OutputPanel Name="Contents" HorizontalExpand="True" VerticalExpand="True" />
<controls:ChatInputBox HorizontalExpand="True" Name="ChatInput" Access="Public" Margin="2"/>
</BoxContainer>
</PanelContainer>
</widgets:ChatBox>

View File

@@ -5,6 +5,7 @@ using Content.Shared.Chat;
using Content.Shared.Input;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
using Robust.Shared.Utility;
@@ -14,7 +15,7 @@ namespace Content.Client.UserInterface.Systems.Chat.Widgets;
[GenerateTypedNameReferences]
#pragma warning disable RA0003
public partial class ChatBox : Control
public partial class ChatBox : UIWidget
#pragma warning restore RA0003
{
private readonly ChatUIController _controller;
@@ -197,7 +198,7 @@ public partial class ChatBox : Control
UpdateSelectedChannel();
// Warn typing indicator about change
EntitySystem.Get<TypingIndicatorSystem>().ClientChangedChatText();
_controller.NotifyChatTextChange();
}
protected override void Dispose(bool disposing)

View File

@@ -11,24 +11,50 @@ namespace Content.Client.UserInterface.Systems.Crafting;
public sealed class CraftingUIController : UIController, IOnStateChanged<GameplayState>
{
private ConstructionMenuPresenter? _presenter;
private MenuButton? _craftingButton;
private MenuButton? CraftingButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.CraftingButton;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_presenter == null);
_presenter = new ConstructionMenuPresenter();
_craftingButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().CraftingButton;
_craftingButton.OnToggled += _presenter.OnHudCraftingButtonToggled;
}
public void OnStateExited(GameplayState state)
{
if (_presenter == null)
return;
_craftingButton!.Pressed = false;
_craftingButton!.OnToggled -= _presenter.OnHudCraftingButtonToggled;
_craftingButton = null;
UnloadButton(_presenter);
_presenter.Dispose();
_presenter = null;
}
internal void UnloadButton(ConstructionMenuPresenter? presenter = null)
{
if (CraftingButton == null)
{
return;
}
if (presenter == null)
{
presenter ??= _presenter;
if (presenter == null)
{
return;
}
}
CraftingButton.Pressed = false;
CraftingButton.OnToggled -= presenter.OnHudCraftingButtonToggled;
}
public void LoadButton()
{
if (CraftingButton == null || _presenter == null)
{
return;
}
CraftingButton.OnToggled += _presenter.OnHudCraftingButtonToggled;
}
}

View File

@@ -26,17 +26,53 @@ public sealed class EscapeUIController : UIController, IOnStateEntered<GameplayS
private Options.UI.EscapeMenu? _escapeWindow;
private MenuButton? _escapeButton;
private MenuButton? EscapeButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.EscapeButton;
public void UnloadButton()
{
if (EscapeButton == null)
{
return;
}
EscapeButton.Pressed = false;
EscapeButton.OnPressed += EscapeButtonOnOnPressed;
if (_escapeWindow == null)
{
return;
}
_escapeWindow.OnClose -= DeactivateButton;
_escapeWindow.OnOpen -= ActivateButton;
}
public void LoadButton()
{
if (EscapeButton == null)
{
return;
}
EscapeButton.OnPressed += EscapeButtonOnOnPressed;
if (_escapeWindow == null)
{
return;
}
_escapeWindow.OnClose += DeactivateButton;
_escapeWindow.OnOpen += ActivateButton;
}
private void ActivateButton() => EscapeButton!.Pressed = true;
private void DeactivateButton() => EscapeButton!.Pressed = false;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_escapeWindow == null);
_escapeButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().EscapeButton;
_escapeButton.OnPressed += EscapeButtonOnOnPressed;
_escapeWindow = UIManager.CreateWindow<Options.UI.EscapeMenu>();
_escapeWindow.OnClose += () => { _escapeButton.Pressed = false; };
_escapeWindow.OnOpen += () => { _escapeButton.Pressed = true; };
_escapeWindow.ChangelogButton.OnPressed += _ =>
{
@@ -87,13 +123,6 @@ public sealed class EscapeUIController : UIController, IOnStateEntered<GameplayS
_escapeWindow = null;
}
if (_escapeButton != null)
{
_escapeButton.OnPressed -= EscapeButtonOnOnPressed;
_escapeButton.Pressed = false;
_escapeButton = null;
}
CommandBinds.Unregister<EscapeUIController>();
}
@@ -119,7 +148,7 @@ public sealed class EscapeUIController : UIController, IOnStateEntered<GameplayS
else
{
_escapeWindow.OpenCentered();
_escapeButton!.Pressed = true;
EscapeButton!.Pressed = true;
}
}
}

View File

@@ -36,9 +36,15 @@ public sealed class GhostUIController : UIController, IOnStateChanged<GameplaySt
system.GhostRoleCountUpdated -= OnRoleCountUpdated;
}
private void UpdateGui()
public void UpdateGui()
{
Gui?.Update(_system?.AvailableGhostRoleCount, _system?.Player?.CanReturnToBody);
if (Gui == null)
{
return;
}
Gui.Visible = _system?.IsGhost ?? false;
Gui.Update(_system?.AvailableGhostRoleCount, _system?.Player?.CanReturnToBody);
}
private void OnPlayerRemoved(GhostComponent component)
@@ -95,7 +101,6 @@ public sealed class GhostUIController : UIController, IOnStateChanged<GameplaySt
Gui.GhostRolesPressed += GhostRolesPressed;
Gui.TargetWindow.WarpClicked += OnWarpClicked;
Gui.Visible = _system?.IsGhost ?? false;
UpdateGui();
}

View File

@@ -10,6 +10,12 @@ public sealed class HandsContainer : ItemSlotUIContainer<HandButton>
public int ColumnLimit { get => _grid.Columns; set => _grid.Columns = value; }
public int MaxButtonCount { get; set; } = 0;
/// <summary>
/// Indexer. This is used to reference a HandsContainer from the
/// controller.
/// </summary>
public string? Indexer { get; set; }
public HandsContainer()
{
AddChild(_grid = new GridContainer());

View File

@@ -238,11 +238,59 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
if (!_handLookup.TryAdd(handName, button))
throw new Exception("Tried to add hand with duplicate name to UI. Name:" + handName);
GetFirstAvailableContainer().AddButton(button);
if (HandsGui != null)
{
HandsGui.HandContainer.AddButton(button);
}
else
{
GetFirstAvailableContainer().AddButton(button);
}
return button;
}
/// <summary>
/// Reload all hands.
/// </summary>
public void ReloadHands()
{
UnloadPlayerHands();
_handsSystem.ReloadHandButtons();
}
/// <summary>
/// Swap hands from one container to the other.
/// </summary>
/// <param name="other"></param>
/// <param name="source"></param>
public void SwapHands(HandsContainer other, HandsContainer? source = null)
{
if (HandsGui == null && source == null)
{
throw new ArgumentException("Cannot swap hands if no source hand container exists!");
}
source ??= HandsGui!.HandContainer;
var transfer = new List<Control>();
foreach (var child in source.Children)
{
if (child is not HandButton)
{
continue;
}
transfer.Add(child);
}
foreach (var control in transfer)
{
source.RemoveChild(control);
other.AddChild(control);
}
}
private void RemoveHand(string handName)
{
RemoveHand(handName, out _);
@@ -266,15 +314,15 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
public string RegisterHandContainer(HandsContainer handContainer)
{
var name = "HandContainer_" + _backupSuffix;
;
if (handContainer.Name == null)
if (handContainer.Indexer == null)
{
handContainer.Name = name;
handContainer.Indexer = name;
_backupSuffix++;
}
else
{
name = handContainer.Name;
name = handContainer.Indexer;
}
_handContainerIndices.Add(name, _handsContainers.Count);

View File

@@ -1,7 +1,9 @@
using Content.Client.UserInterface.Systems.Hands;
using Content.Client.UserInterface.Systems.Hands.Controls;
using Content.Client.UserInterface.Systems.Hotbar.Widgets;
using Content.Client.UserInterface.Systems.Inventory;
using Content.Client.UserInterface.Systems.Inventory.Controls;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
namespace Content.Client.UserInterface.Systems.Hotbar;
@@ -18,4 +20,46 @@ public sealed class HotbarUIController : UIController
_hands.RegisterHandContainer(handsContainer);
_inventory.RegisterInventoryBarContainer(inventoryBar);
}
public void ReloadHotbar()
{
if (UIManager.ActiveScreen == null)
{
return;
}
var hotbar = UIManager.ActiveScreen.GetWidget<HotbarGui>();
if (hotbar == null)
{
return;
}
foreach (var container in GetAllItemSlotContainers(hotbar))
{
// Yes, this is dirty.
container.SlotGroup = container.SlotGroup;
}
_hands?.ReloadHands();
_inventory?.ReloadSlots();
_inventory?.RegisterInventoryBarContainer(hotbar.InventoryHotbar);
}
private IEnumerable<ItemSlotButtonContainer> GetAllItemSlotContainers(Control gui)
{
var result = new List<ItemSlotButtonContainer>();
foreach (var child in gui.Children)
{
if (child is ItemSlotButtonContainer container)
{
result.Add(container);
}
result.AddRange(GetAllItemSlotContainers(child));
}
return result;
}
}

View File

@@ -15,6 +15,7 @@
/>
<inventory:ItemSlotButtonContainer
Name="InventoryHotbar"
Access="Public"
Visible="False"
Columns="10"
SlotGroup="Default"
@@ -34,7 +35,7 @@
HorizontalExpand="True"/>
<hands:HandsContainer
Name="HandContainer"
Access="Protected"
Access="Public"
HorizontalAlignment="Center"
ColumnLimit="6" />
<inventory:ItemSlotButtonContainer

View File

@@ -31,20 +31,18 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
private StrippingWindow? _strippingWindow;
private ItemSlotButtonContainer? _inventoryHotbar;
private MenuButton? _inventoryButton;
private MenuButton? InventoryButton => UIManager.ActiveScreen?.GetWidget<MenuBar.Widgets.GameTopMenuBar>()?.InventoryButton;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_strippingWindow == null);
_strippingWindow = UIManager.CreateWindow<StrippingWindow>();
_inventoryButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().InventoryButton;
LayoutContainer.SetAnchorPreset(_strippingWindow, LayoutContainer.LayoutPreset.Center);
//bind open inventory key to OpenInventoryMenu;
CommandBinds.Builder
.Bind(ContentKeyFunctions.OpenInventoryMenu, InputCmdHandler.FromDelegate(_ => ToggleInventoryBar()))
.Register<ClientInventorySystem>();
_inventoryButton.OnPressed += InventoryButtonPressed;
}
public void OnStateExited(GameplayState state)
@@ -60,14 +58,27 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
_inventoryHotbar.Visible = false;
}
if (_inventoryButton != null)
CommandBinds.Unregister<ClientInventorySystem>();
}
public void UnloadButton()
{
if (InventoryButton == null)
{
_inventoryButton.OnPressed -= InventoryButtonPressed;
_inventoryButton.Pressed = false;
_inventoryButton = null;
return;
}
CommandBinds.Unregister<ClientInventorySystem>();
InventoryButton.OnPressed -= InventoryButtonPressed;
}
public void LoadButton()
{
if (InventoryButton == null)
{
return;
}
InventoryButton.OnPressed += InventoryButtonPressed;
}
private SlotButton CreateSlotButton(SlotData data)
@@ -166,14 +177,14 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
if (_inventoryHotbar.Visible)
{
_inventoryHotbar.Visible = false;
if (_inventoryButton != null)
_inventoryButton.Pressed = false;
if (InventoryButton != null)
InventoryButton.Pressed = false;
}
else
{
_inventoryHotbar.Visible = true;
if (_inventoryButton != null)
_inventoryButton.Pressed = true;
if (InventoryButton != null)
InventoryButton.Pressed = true;
}
}
@@ -279,6 +290,11 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
slotGroup.RemoveButton(data.SlotName);
}
public void ReloadSlots()
{
_inventorySystem.ReloadInventory();
}
private void LoadSlots(ClientInventoryComponent clientInv)
{
UnloadSlots();
@@ -322,7 +338,6 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
if (_slotGroups.TryAdd(slotContainer.SlotGroup, slotContainer))
return true;
Logger.Warning("Could not add container for slotgroup: " + slotContainer.SlotGroup);
return false;
}

View File

@@ -0,0 +1,51 @@
using Content.Client.Gameplay;
using Content.Client.UserInterface.Systems.Actions;
using Content.Client.UserInterface.Systems.Admin;
using Content.Client.UserInterface.Systems.Bwoink;
using Content.Client.UserInterface.Systems.Character;
using Content.Client.UserInterface.Systems.Crafting;
using Content.Client.UserInterface.Systems.EscapeMenu;
using Content.Client.UserInterface.Systems.Inventory;
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Client.UserInterface.Systems.Sandbox;
using Robust.Client.UserInterface.Controllers;
namespace Content.Client.UserInterface.Systems.MenuBar;
public sealed class GameTopMenuBarUIController : UIController
{
[Dependency] private readonly EscapeUIController _escape = default!;
[Dependency] private readonly InventoryUIController _inventory = default!;
[Dependency] private readonly AdminUIController _admin = default!;
[Dependency] private readonly CharacterUIController _character = default!;
[Dependency] private readonly CraftingUIController _crafting = default!;
[Dependency] private readonly AHelpUIController _ahelp = default!;
[Dependency] private readonly ActionUIController _action = default!;
[Dependency] private readonly SandboxUIController _sandbox = default!;
private GameTopMenuBar? GameTopMenuBar => UIManager.GetActiveUIWidgetOrNull<GameTopMenuBar>();
public void UnloadButtons()
{
_escape.UnloadButton();
_inventory.UnloadButton();
_admin.UnloadButton();
_character.UnloadButton();
_crafting.UnloadButton();
_ahelp.UnloadButton();
_action.UnloadButton();
_sandbox.UnloadButton();
}
public void LoadButtons()
{
_escape.LoadButton();
_inventory.LoadButton();
_admin.LoadButton();
_character.LoadButton();
_crafting.LoadButton();
_ahelp.LoadButton();
_action.LoadButton();
_sandbox.LoadButton();
}
}

View File

@@ -20,6 +20,7 @@
BoundKey = "{x:Static ic:EngineKeyFunctions.EscapeMenu}"
ToolTip="{Loc 'game-hud-open-escape-menu-button-tooltip'}"
MinSize="70 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonOpenRight}"
/>
<ui:MenuButton
@@ -29,6 +30,7 @@
ToolTip="{Loc 'game-hud-open-character-menu-button-tooltip'}"
BoundKey = "{x:Static is:ContentKeyFunctions.OpenCharacterMenu}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -38,6 +40,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenInventoryMenu}"
ToolTip="{Loc 'game-hud-open-inventory-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -47,6 +50,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenCraftingMenu}"
ToolTip="{Loc 'game-hud-open-crafting-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -56,6 +60,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenActionsMenu}"
ToolTip="{Loc 'game-hud-open-actions-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -65,6 +70,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenAdminMenu}"
ToolTip="{Loc 'game-hud-open-admin-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -74,6 +80,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenSandboxWindow}"
ToolTip="{Loc 'game-hud-open-sandbox-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<ui:MenuButton
@@ -83,6 +90,7 @@
BoundKey = "{x:Static is:ContentKeyFunctions.OpenAHelp}"
ToolTip="{Loc 'ui-options-function-open-ahelp'}"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonOpenLeft}"
/>
</widgets:GameTopMenuBar>

View File

@@ -43,13 +43,11 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
private TileSpawningUIController TileSpawningController => UIManager.GetUIController<TileSpawningUIController>();
private DecalPlacerUIController DecalPlacerController => UIManager.GetUIController<DecalPlacerUIController>();
private MenuButton? _sandboxButton;
private MenuButton? SandboxButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.SandboxButton;
public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(_window == null);
_sandboxButton = UIManager.GetActiveUIWidget<MenuBar.Widgets.GameTopMenuBar>().SandboxButton;
_sandboxButton.OnPressed += SandboxButtonPressed;
EnsureWindow();
CheckSandboxVisibility();
@@ -68,13 +66,33 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
.Register<SandboxSystem>();
}
public void UnloadButton()
{
if (SandboxButton == null)
{
return;
}
SandboxButton.OnPressed -= SandboxButtonPressed;
}
public void LoadButton()
{
if (SandboxButton == null)
{
return;
}
SandboxButton.OnPressed += SandboxButtonPressed;
}
private void EnsureWindow()
{
if(_window is { Disposed: false })
return;
_window = UIManager.CreateWindow<SandboxWindow>();
_window.OnOpen += () => { _sandboxButton!.Pressed = true; };
_window.OnClose += () => { _sandboxButton!.Pressed = false; };
_window.OnOpen += () => { SandboxButton!.Pressed = true; };
_window.OnClose += () => { SandboxButton!.Pressed = false; };
_window.ToggleLightButton.Pressed = !_light.Enabled;
_window.ToggleFovButton.Pressed = !_eye.CurrentEye.DrawFov;
_window.ToggleShadowsButton.Pressed = !_light.DrawShadows;
@@ -100,10 +118,10 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
private void CheckSandboxVisibility()
{
if (_sandboxButton == null)
if (SandboxButton == null)
return;
_sandboxButton.Visible = _sandbox.SandboxAllowed;
SandboxButton.Visible = _sandbox.SandboxAllowed;
}
public void OnStateExited(GameplayState state)
@@ -114,13 +132,6 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
_window = null;
}
if (_sandboxButton != null)
{
_sandboxButton.Pressed = false;
_sandboxButton.OnPressed -= SandboxButtonPressed;
_sandboxButton = null;
}
CommandBinds.Unregister<SandboxSystem>();
}

View File

@@ -0,0 +1,89 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.CCVar;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controllers;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
namespace Content.Client.UserInterface.Systems.Viewport;
public sealed class ViewportUIController : UIController
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IPlayerManager _playerMan = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
public static readonly Vector2i ViewportSize = (EyeManager.PixelsPerMeter * 21, EyeManager.PixelsPerMeter * 15);
public const int ViewportHeight = 15;
private MainViewport? Viewport => UIManager.ActiveScreen?.GetWidget<MainViewport>();
public override void Initialize()
{
_configurationManager.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportRatio());
_configurationManager.OnValueChanged(CCVars.ViewportMaximumWidth, _ => UpdateViewportRatio());
_configurationManager.OnValueChanged(CCVars.ViewportWidth, _ => UpdateViewportRatio());
}
private void UpdateViewportRatio()
{
if (Viewport == null)
{
return;
}
var min = _configurationManager.GetCVar(CCVars.ViewportMinimumWidth);
var max = _configurationManager.GetCVar(CCVars.ViewportMaximumWidth);
var width = _configurationManager.GetCVar(CCVars.ViewportWidth);
if (width < min || width > max)
{
width = CCVars.ViewportWidth.DefaultValue;
}
Viewport.Viewport.ViewportSize = (EyeManager.PixelsPerMeter * width, EyeManager.PixelsPerMeter * ViewportHeight);
}
public void ReloadViewport()
{
if (Viewport == null)
{
return;
}
UpdateViewportRatio();
Viewport.Viewport.HorizontalExpand = true;
Viewport.Viewport.VerticalExpand = true;
_eyeManager.MainViewport = Viewport.Viewport;
}
public override void FrameUpdate(FrameEventArgs e)
{
if (Viewport == null)
{
return;
}
base.FrameUpdate(e);
Viewport.Viewport.Eye = _eyeManager.CurrentEye;
// verify that the current eye is not "null". Fuck IEyeManager.
var ent = _playerMan.LocalPlayer?.ControlledEntity;
if (_eyeManager.CurrentEye.Position != default || ent == null)
return;
_entMan.TryGetComponent(ent, out EyeComponent? eye);
if (eye?.Eye == _eyeManager.CurrentEye
&& _entMan.GetComponent<TransformComponent>(ent.Value).WorldPosition == default)
return; // nothing to worry about, the player is just in null space... actually that is probably a problem?
// Currently, this shouldn't happen. This likely happened because the main eye was set to null. When this
// does happen it can create hard to troubleshoot bugs, so lets print some helpful warnings:
Logger.Warning($"Main viewport's eye is in nullspace (main eye is null?). Attached entity: {_entMan.ToPrettyString(ent.Value)}. Entity has eye comp: {eye != null}");
}
}