]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix screenspace popups (#24987)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Sat, 10 Feb 2024 08:51:11 +0000 (19:51 +1100)
committerGitHub <noreply@github.com>
Sat, 10 Feb 2024 08:51:11 +0000 (00:51 -0800)
* Fix screenspace popups

Never got around to it earlier but need to draw it above UI controls.

* Minor null change

Content.Client/Popups/PopupOverlay.cs
Content.Client/Popups/PopupSystem.cs
Content.Client/Popups/PopupUIController.cs [new file with mode: 0644]

index 5adc2e1ff0c70995a4a7dc77cd3378d65f0ee13c..1305d8bb947b98743fc16285788a05d3f4927772 100644 (file)
@@ -1,12 +1,6 @@
-using System.Numerics;
-using Content.Client.Examine;
-using Content.Shared.CCVar;
 using Content.Shared.Examine;
-using Content.Shared.Interaction;
-using Content.Shared.Popups;
 using Robust.Client.Graphics;
 using Robust.Client.Player;
-using Robust.Client.ResourceManagement;
 using Robust.Client.UserInterface;
 using Robust.Shared;
 using Robust.Shared.Configuration;
@@ -26,11 +20,9 @@ public sealed class PopupOverlay : Overlay
     private readonly IPlayerManager _playerMgr;
     private readonly IUserInterfaceManager _uiManager;
     private readonly PopupSystem _popup;
+    private readonly PopupUIController _controller;
 
     private readonly ShaderInstance _shader;
-    private readonly Font _smallFont;
-    private readonly Font _mediumFont;
-    private readonly Font _largeFont;
 
     public override OverlaySpace Space => OverlaySpace.ScreenSpace;
 
@@ -39,8 +31,8 @@ public sealed class PopupOverlay : Overlay
         IEntityManager entManager,
         IPlayerManager playerMgr,
         IPrototypeManager protoManager,
-        IResourceCache cache,
         IUserInterfaceManager uiManager,
+        PopupUIController controller,
         PopupSystem popup)
     {
         _configManager = configManager;
@@ -48,11 +40,9 @@ public sealed class PopupOverlay : Overlay
         _playerMgr = playerMgr;
         _uiManager = uiManager;
         _popup = popup;
+        _controller = controller;
 
         _shader = protoManager.Index<ShaderPrototype>("unshaded").Instance();
-        _smallFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10);
-        _mediumFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12);
-        _largeFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-BoldItalic.ttf"), 14);
     }
 
     protected override void Draw(in OverlayDrawArgs args)
@@ -68,19 +58,18 @@ public sealed class PopupOverlay : Overlay
             scale = _uiManager.DefaultUIScale;
 
         DrawWorld(args.ScreenHandle, args, scale);
-        DrawScreen(args.ScreenHandle, args, scale);
 
         args.DrawingHandle.UseShader(null);
     }
 
     private void DrawWorld(DrawingHandleScreen worldHandle, OverlayDrawArgs args, float scale)
     {
-        if (_popup.WorldLabels.Count == 0)
+        if (_popup.WorldLabels.Count == 0 || args.ViewportControl == null)
             return;
 
-        var matrix = args.ViewportControl!.GetWorldToScreenMatrix();
+        var matrix = args.ViewportControl.GetWorldToScreenMatrix();
         var viewPos = new MapCoordinates(args.WorldAABB.Center, args.MapId);
-        var ourEntity = _playerMgr.LocalPlayer?.ControlledEntity;
+        var ourEntity = _playerMgr.LocalEntity;
 
         foreach (var popup in _popup.WorldLabels)
         {
@@ -92,62 +81,12 @@ public sealed class PopupOverlay : Overlay
             var distance = (mapPos.Position - args.WorldBounds.Center).Length();
 
             // Should handle fade here too wyci.
-            if (!args.WorldAABB.Contains(mapPos.Position) || !ExamineSystemShared.InRangeUnOccluded(viewPos, mapPos, distance,
+            if (!args.WorldBounds.Contains(mapPos.Position) || !ExamineSystemShared.InRangeUnOccluded(viewPos, mapPos, distance,
                     e => e == popup.InitialPos.EntityId || e == ourEntity, entMan: _entManager))
                 continue;
 
             var pos = matrix.Transform(mapPos.Position);
-            DrawPopup(popup, worldHandle, pos, scale);
+            _controller.DrawPopup(popup, worldHandle, pos, scale);
         }
     }
-
-    private void DrawScreen(DrawingHandleScreen screenHandle, OverlayDrawArgs args, float scale)
-    {
-        foreach (var popup in _popup.CursorLabels)
-        {
-            // Different window
-            if (popup.InitialPos.Window != args.ViewportControl?.Window?.Id)
-                continue;
-
-            DrawPopup(popup, screenHandle, popup.InitialPos.Position, scale);
-        }
-    }
-
-    private void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale)
-    {
-        var lifetime = PopupSystem.GetPopupLifetime(popup);
-
-        // Keep alpha at 1 until TotalTime passes half its lifetime, then gradually decrease to 0.
-        var alpha = MathF.Min(1f, 1f - MathF.Max(0f, popup.TotalTime - lifetime / 2) * 2 / lifetime);
-
-        var updatedPosition = position - new Vector2(0f, MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime)));
-        var font = _smallFont;
-        var color = Color.White.WithAlpha(alpha);
-
-        switch (popup.Type)
-        {
-            case PopupType.SmallCaution:
-                color = Color.Red;
-                break;
-            case PopupType.Medium:
-                font = _mediumFont;
-                color = Color.LightGray;
-                break;
-            case PopupType.MediumCaution:
-                font = _mediumFont;
-                color = Color.Red;
-                break;
-            case PopupType.Large:
-                font = _largeFont;
-                color = Color.LightGray;
-                break;
-            case PopupType.LargeCaution:
-                font = _largeFont;
-                color = Color.Red;
-                break;
-        }
-
-        var dimensions = handle.GetDimensions(font, popup.Text, scale);
-        handle.DrawString(font, updatedPosition - dimensions / 2f, popup.Text, scale, color.WithAlpha(alpha));
-    }
 }
index d9e66c79fa9f2e9831c0507734aecc5af809b178..2c923ae3a71cc0dc513a8d06de785e3a7563e266 100644 (file)
@@ -23,7 +23,6 @@ namespace Content.Client.Popups
         [Dependency] private readonly IOverlayManager _overlay = default!;
         [Dependency] private readonly IPlayerManager _playerManager = default!;
         [Dependency] private readonly IPrototypeManager _prototype = default!;
-        [Dependency] private readonly IResourceCache _resource = default!;
         [Dependency] private readonly IGameTiming _timing = default!;
         [Dependency] private readonly IUserInterfaceManager _uiManager = default!;
         [Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
@@ -45,7 +44,14 @@ namespace Content.Client.Popups
             SubscribeNetworkEvent<PopupEntityEvent>(OnPopupEntityEvent);
             SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundRestart);
             _overlay
-                .AddOverlay(new PopupOverlay(_configManager, EntityManager, _playerManager, _prototype, _resource, _uiManager, this));
+                .AddOverlay(new PopupOverlay(
+                    _configManager,
+                    EntityManager,
+                    _playerManager,
+                    _prototype,
+                    _uiManager,
+                    _uiManager.GetUIController<PopupUIController>(),
+                    this));
         }
 
         public override void Shutdown()
diff --git a/Content.Client/Popups/PopupUIController.cs b/Content.Client/Popups/PopupUIController.cs
new file mode 100644 (file)
index 0000000..8ce8ae2
--- /dev/null
@@ -0,0 +1,121 @@
+using System.Numerics;
+using Content.Client.Gameplay;
+using Content.Shared.Popups;
+using Robust.Client.Graphics;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controllers;
+
+namespace Content.Client.Popups;
+
+/// <summary>
+/// Handles screens-space popups. World popups are handled via PopupOverlay.
+/// </summary>
+public sealed class PopupUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>
+{
+    [UISystemDependency] private readonly PopupSystem? _popup = default!;
+
+    private Font _smallFont = default!;
+    private Font _mediumFont = default!;
+    private Font _largeFont = default!;
+
+    private PopupRootControl? _popupControl;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+        var cache = IoCManager.Resolve<IResourceCache>();
+
+        _smallFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10);
+        _mediumFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12);
+        _largeFont = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-BoldItalic.ttf"), 14);
+    }
+
+    public void OnStateEntered(GameplayState state)
+    {
+        _popupControl = new PopupRootControl(_popup, this);
+
+        UIManager.RootControl.AddChild(_popupControl);
+    }
+
+    public void OnStateExited(GameplayState state)
+    {
+        if (_popupControl == null)
+            return;
+
+        UIManager.RootControl.RemoveChild(_popupControl);
+        _popupControl = null;
+    }
+
+    public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale)
+    {
+        var lifetime = PopupSystem.GetPopupLifetime(popup);
+
+        // Keep alpha at 1 until TotalTime passes half its lifetime, then gradually decrease to 0.
+        var alpha = MathF.Min(1f, 1f - MathF.Max(0f, popup.TotalTime - lifetime / 2) * 2 / lifetime);
+
+        var updatedPosition = position - new Vector2(0f, MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime)));
+        var font = _smallFont;
+        var color = Color.White.WithAlpha(alpha);
+
+        switch (popup.Type)
+        {
+            case PopupType.SmallCaution:
+                color = Color.Red;
+                break;
+            case PopupType.Medium:
+                font = _mediumFont;
+                color = Color.LightGray;
+                break;
+            case PopupType.MediumCaution:
+                font = _mediumFont;
+                color = Color.Red;
+                break;
+            case PopupType.Large:
+                font = _largeFont;
+                color = Color.LightGray;
+                break;
+            case PopupType.LargeCaution:
+                font = _largeFont;
+                color = Color.Red;
+                break;
+        }
+
+        var dimensions = handle.GetDimensions(font, popup.Text, scale);
+        handle.DrawString(font, updatedPosition - dimensions / 2f, popup.Text, scale, color.WithAlpha(alpha));
+    }
+
+    /// <summary>
+    /// Handles drawing all screen popups.
+    /// </summary>
+    private sealed class PopupRootControl : Control
+    {
+        private readonly PopupSystem? _popup;
+        private readonly PopupUIController _controller;
+
+        public PopupRootControl(PopupSystem? system, PopupUIController controller)
+        {
+            _popup = system;
+            _controller = controller;
+        }
+
+        protected override void Draw(DrawingHandleScreen handle)
+        {
+            base.Draw(handle);
+
+            if (_popup == null)
+                return;
+
+            // Different window
+            var windowId = UserInterfaceManager.RootControl.Window.Id;
+
+            foreach (var popup in _popup.CursorLabels)
+            {
+                if (popup.InitialPos.Window != windowId)
+                    continue;
+
+                _controller.DrawPopup(popup, handle, popup.InitialPos.Position, UIScale);
+            }
+        }
+    }
+}