diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index dc45979778..86a9e5837f 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -133,6 +133,7 @@ namespace Content.Client factory.RegisterIgnore("AiController"); factory.RegisterIgnore("PlayerInputMover"); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); @@ -198,6 +199,7 @@ namespace Content.Client IoCManager.Resolve().Initialize(); IoCManager.Resolve().AddOverlay(new ParallaxOverlay()); IoCManager.Resolve().Initialize(); + IoCManager.Resolve().Initialize(); } public override void Update(ModUpdateLevel level, float frameTime) diff --git a/Content.Client/EscapeMenuOwner.cs b/Content.Client/EscapeMenuOwner.cs index d9e41b1c20..45ba4bc5cb 100644 --- a/Content.Client/EscapeMenuOwner.cs +++ b/Content.Client/EscapeMenuOwner.cs @@ -9,6 +9,7 @@ using Robust.Shared.Input; using Robust.Shared.Interfaces.Configuration; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; +using Robust.Shared.Players; using Robust.Shared.Prototypes; namespace Content.Client @@ -16,14 +17,15 @@ namespace Content.Client internal sealed class EscapeMenuOwner : IEscapeMenuOwner { #pragma warning disable 649 - [Dependency] private readonly IStateManager _stateManager; [Dependency] private readonly IClientConsole _clientConsole; - [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager; + [Dependency] private readonly IConfigurationManager _configurationManager; + [Dependency] private readonly IInputManager _inputManager; [Dependency] private readonly IPlacementManager _placementManager; [Dependency] private readonly IPrototypeManager _prototypeManager; [Dependency] private readonly IResourceCache _resourceCache; - [Dependency] private readonly IConfigurationManager _configurationManager; - [Dependency] private readonly IInputManager _inputManager; + [Dependency] private readonly IStateManager _stateManager; + [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager; + [Dependency] private readonly IGameHud _gameHud; #pragma warning restore 649 private EscapeMenu _escapeMenu; @@ -31,6 +33,8 @@ namespace Content.Client public void Initialize() { _stateManager.OnStateChanged += StateManagerOnOnStateChanged; + + _gameHud.EscapeButtonToggled += _setOpenValue; } private void StateManagerOnOnStateChanged(StateChangedEventArgs obj) @@ -44,26 +48,11 @@ namespace Content.Client Visible = false }; + _escapeMenu.OnClose += () => _gameHud.EscapeButtonDown = false; + _escapeMenu.AddToScreen(); - var escapeMenuCommand = InputCmdHandler.FromDelegate(session => - { - if (_escapeMenu.Visible) - { - if (_escapeMenu.IsAtFront()) - { - _escapeMenu.Visible = false; - } - else - { - _escapeMenu.MoveToFront(); - } - } - else - { - _escapeMenu.OpenCentered(); - } - }); + var escapeMenuCommand = InputCmdHandler.FromDelegate(Enabled); _inputManager.SetInputCommand(EngineKeyFunctions.EscapeMenu, escapeMenuCommand); } @@ -76,6 +65,39 @@ namespace Content.Client _inputManager.SetInputCommand(EngineKeyFunctions.EscapeMenu, null); } } + + private void Enabled(ICommonSession session) + { + if (_escapeMenu.Visible) + { + if (_escapeMenu.IsAtFront()) + { + _setOpenValue(false); + } + else + { + _escapeMenu.MoveToFront(); + } + } + else + { + _setOpenValue(true); + } + } + + private void _setOpenValue(bool value) + { + if (value) + { + _gameHud.EscapeButtonDown = true; + _escapeMenu.OpenCentered(); + } + else + { + _gameHud.EscapeButtonDown = false; + _escapeMenu.Visible = false; + } + } } public interface IEscapeMenuOwner diff --git a/Content.Client/GameTicking/ClientGameTicker.cs b/Content.Client/GameTicking/ClientGameTicker.cs index 1ae9c5d814..a89611e48a 100644 --- a/Content.Client/GameTicking/ClientGameTicker.cs +++ b/Content.Client/GameTicking/ClientGameTicker.cs @@ -35,6 +35,7 @@ namespace Content.Client.GameTicking [Dependency] private ILocalizationManager _localization; [Dependency] private IResourceCache _resourceCache; [Dependency] private IPlayerManager _playerManager; + [Dependency] private IGameHud _gameHud; #pragma warning restore 649 [ViewVariables] private bool _areWeReady; @@ -177,6 +178,8 @@ namespace Content.Client.GameTicking _tutorialButton = null; } + _gameHud.RootControl?.Parent.RemoveChild(_gameHud.RootControl); + _tickerState = TickerState.InLobby; _lobby = new LobbyGui(_localization, _resourceCache); @@ -248,6 +251,7 @@ namespace Content.Client.GameTicking _gameChat = new ChatBox(); _userInterfaceManager.StateRoot.AddChild(_gameChat); + _userInterfaceManager.StateRoot.AddChild(_gameHud.RootControl); _chatManager.SetChatBox(_gameChat); _tutorialButton = new TutorialButton(); _userInterfaceManager.StateRoot.AddChild(_tutorialButton); diff --git a/Content.Client/Interfaces/IClientGameTicker.cs b/Content.Client/Interfaces/IClientGameTicker.cs index 16d3608caa..2b7d14e000 100644 --- a/Content.Client/Interfaces/IClientGameTicker.cs +++ b/Content.Client/Interfaces/IClientGameTicker.cs @@ -1,3 +1,4 @@ +using Content.Client.UserInterface; using Robust.Client; namespace Content.Client.Interfaces diff --git a/Content.Client/UserInterface/GameHud.cs b/Content.Client/UserInterface/GameHud.cs new file mode 100644 index 0000000000..a147d828bd --- /dev/null +++ b/Content.Client/UserInterface/GameHud.cs @@ -0,0 +1,65 @@ +using System; +using Content.Client.Utility; +using Robust.Client.Interfaces.ResourceManagement; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.IoC; +using Robust.Shared.Localization; + +namespace Content.Client.UserInterface +{ + public interface IGameHud + { + Control RootControl { get; } + + bool EscapeButtonDown { get; set; } + Action EscapeButtonToggled { get; set; } + void Initialize(); + } + + /// + /// Responsible for laying out the default game HUD. + /// + internal sealed class GameHud : IGameHud + { + public const string StyleClassTopMenuButton = "topMenuButton"; + + private TextureButton _buttonEscapeMenu; + +#pragma warning disable 649 + [Dependency] private readonly IResourceCache _resourceCache; + [Dependency] private readonly ILocalizationManager _localizationManager; +#pragma warning restore 649 + + public void Initialize() + { + RootControl = new Control(); + + RootControl.SetAnchorPreset(Control.LayoutPreset.Wide); + + _buttonEscapeMenu = new TextureButton + { + TextureNormal = _resourceCache.GetTexture("/Textures/UserInterface/hamburger.svg.96dpi.png"), + ToggleMode = true, + ToolTip = _localizationManager.GetString("Open escape menu.") + }; + + _buttonEscapeMenu.OnToggled += args => { EscapeButtonToggled?.Invoke(args.Pressed); }; + + _buttonEscapeMenu.AddStyleClass(StyleClassTopMenuButton); + + RootControl.AddChild(_buttonEscapeMenu); + _buttonEscapeMenu.SetAnchorAndMarginPreset(Control.LayoutPreset.TopLeft, margin: 20); + } + + public Control RootControl { get; private set; } + + public bool EscapeButtonDown + { + get => _buttonEscapeMenu.Pressed; + set => _buttonEscapeMenu.Pressed = value; + } + + public Action EscapeButtonToggled { get; set; } + } +} diff --git a/Content.Client/UserInterface/NanoStyle.cs b/Content.Client/UserInterface/NanoStyle.cs index d6379e9294..926d9296fc 100644 --- a/Content.Client/UserInterface/NanoStyle.cs +++ b/Content.Client/UserInterface/NanoStyle.cs @@ -440,7 +440,23 @@ namespace Content.Client.UserInterface new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassPowerStateGood}, null, null), new [] { new StyleProperty(Label.StylePropertyFontColor, new Color(0.024f, 0.8f, 0.0f)) - }), + }), + + // Those buttons on the top left. + new StyleRule(new SelectorElement(typeof(TextureButton), new []{GameHud.StyleClassTopMenuButton}, null, TextureButton.StylePseudoClassNormal), new [] + { + new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#7b7e9e")) + }), + + new StyleRule(new SelectorElement(typeof(TextureButton), new []{GameHud.StyleClassTopMenuButton}, null, TextureButton.StylePseudoClassHover), new [] + { + new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#8285a3")) + }), + + new StyleRule(new SelectorElement(typeof(TextureButton), new []{GameHud.StyleClassTopMenuButton}, null, TextureButton.StylePseudoClassPressed), new [] + { + new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#00b061")) + }), }); } } diff --git a/Resources/Textures/UserInterface/hamburger.svg b/Resources/Textures/UserInterface/hamburger.svg new file mode 100644 index 0000000000..9a998ba3db --- /dev/null +++ b/Resources/Textures/UserInterface/hamburger.svg @@ -0,0 +1,85 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/Resources/Textures/UserInterface/hamburger.svg.96dpi.png b/Resources/Textures/UserInterface/hamburger.svg.96dpi.png new file mode 100644 index 0000000000..e1501472ac Binary files /dev/null and b/Resources/Textures/UserInterface/hamburger.svg.96dpi.png differ