mirror of
https://github.com/corvax-team/ss14-wl.git
synced 2026-02-14 19:29:57 +01:00
Fix screenspace popups (#24987)
* Fix screenspace popups Never got around to it earlier but need to draw it above UI controls. * Minor null change
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
121
Content.Client/Popups/PopupUIController.cs
Normal file
121
Content.Client/Popups/PopupUIController.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user