From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 10 Feb 2024 08:51:11 +0000 (+1100) Subject: Fix screenspace popups (#24987) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=560ea9775a561b9d516a838687733e8983bbe9a0;p=space-station-14.git Fix screenspace popups (#24987) * Fix screenspace popups Never got around to it earlier but need to draw it above UI controls. * Minor null change --- diff --git a/Content.Client/Popups/PopupOverlay.cs b/Content.Client/Popups/PopupOverlay.cs index 5adc2e1ff0..1305d8bb94 100644 --- a/Content.Client/Popups/PopupOverlay.cs +++ b/Content.Client/Popups/PopupOverlay.cs @@ -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("unshaded").Instance(); - _smallFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10); - _mediumFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12); - _largeFont = new VectorFont(cache.GetResource("/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)); - } } diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index d9e66c79fa..2c923ae3a7 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -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(OnPopupEntityEvent); SubscribeNetworkEvent(OnRoundRestart); _overlay - .AddOverlay(new PopupOverlay(_configManager, EntityManager, _playerManager, _prototype, _resource, _uiManager, this)); + .AddOverlay(new PopupOverlay( + _configManager, + EntityManager, + _playerManager, + _prototype, + _uiManager, + _uiManager.GetUIController(), + this)); } public override void Shutdown() diff --git a/Content.Client/Popups/PopupUIController.cs b/Content.Client/Popups/PopupUIController.cs new file mode 100644 index 0000000000..8ce8ae21e1 --- /dev/null +++ b/Content.Client/Popups/PopupUIController.cs @@ -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; + +/// +/// Handles screens-space popups. World popups are handled via PopupOverlay. +/// +public sealed class PopupUIController : UIController, IOnStateEntered, IOnStateExited +{ + [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(); + + _smallFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10); + _mediumFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12); + _largeFont = new VectorFont(cache.GetResource("/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)); + } + + /// + /// Handles drawing all screen popups. + /// + 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); + } + } + } +}