-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;
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;
IEntityManager entManager,
IPlayerManager playerMgr,
IPrototypeManager protoManager,
- IResourceCache cache,
IUserInterfaceManager uiManager,
+ PopupUIController controller,
PopupSystem popup)
{
_configManager = configManager;
_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)
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)
{
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));
- }
}
--- /dev/null
+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);
+ }
+ }
+ }
+}