Files
RobustToolbox/Robust.Client/UserInterface/CustomControls/ViewportContainer.cs
83c2a1be11 [Dependency] source generator part 2 (#6550)
* [Dependency] source generator

No more reflection, no more codegen at runtime

Also various changes to Roslyn helpers to make this easier to write.

Requires all types with dependencies to be partial and not have readonly dependency fields. An analyzer enforces this at warning level, the previous injection strategies have remained in the code *for now* as a fallback.

No fallback is available for [field: Dependency] properties, due to a Roslyn bug.

Code Fixes exist. We love Roslyn

* Apply dependencies generator changes to all code

* Release notes

* Preprocessor got hands

* Handle nullable dependencies

These are bad but gotta deal with it.

* Apply suggestions from code review

Co-authored-by: Moony <moony@hellomouse.net>

* Fine, let's not use collection expressions

---------

Co-authored-by: Moony <moony@hellomouse.net>
2026-05-08 12:38:33 +02:00

172 lines
5.0 KiB
C#

using System.Numerics;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Robust.Client.UserInterface.CustomControls
{
/// <summary>
/// A viewport container shows a viewport.
/// </summary>
[Virtual]
public partial class ViewportContainer : Control, IViewportControl
{
[Dependency] private IClyde _displayManager = default!;
[Dependency] private IEntityManager _entityManager = default!;
[Dependency] private IInputManager _inputManager = default!;
public IClydeViewport? Viewport { get; set; }
private Vector2 _viewportResolution = new Vector2(1f, 1f);
/// <summary>
/// This controls the render target size, *as a fraction of the control size.*
/// Combined with controlling the Eye, this allows downscaling the game.
/// </summary>
public Vector2 ViewportResolution
{
get => _viewportResolution;
set
{
_viewportResolution = value;
Resized();
}
}
public ViewportContainer()
{
IoCManager.InjectDependencies(this);
MouseFilter = MouseFilterMode.Stop;
Resized();
}
protected internal override void KeyBindDown(GUIBoundKeyEventArgs args)
{
base.KeyBindDown(args);
if (args.Handled)
return;
_inputManager.ViewportKeyEvent(this, args);
}
protected internal override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
if (args.Handled)
return;
_inputManager.ViewportKeyEvent(this, args);
}
// -- Handlers: Out --
protected internal override void Draw(IRenderHandle handle)
{
base.Draw(handle);
if (Viewport == null)
{
handle.DrawingHandleScreen.DrawRect(UIBox2.FromDimensions(new Vector2(0, 0), Size * UIScale), Color.Red);
}
else
{
if (Viewport.Eye == null)
return;
var viewportBounds = UIBox2i.FromDimensions(GlobalPixelPosition, PixelSize);
Viewport.RenderScreenOverlaysBelow(handle, this, viewportBounds);
Viewport.Render();
handle.DrawingHandleScreen.DrawTextureRect(Viewport.RenderTarget.Texture,
UIBox2.FromDimensions(new Vector2(0, 0), (Vector2i)(Viewport.Size / _viewportResolution)));
Viewport.RenderScreenOverlaysAbove(handle, this, viewportBounds);
}
}
protected sealed override void Resized()
{
Viewport?.Dispose();
Viewport = _displayManager.CreateViewport(
Vector2i.ComponentMax((1, 1), (Vector2i)(PixelSize * _viewportResolution)),
"ViewportContainerViewport");
}
// -- Handlers: In --
// -- Utils / S2M-M2S Base --
public MapCoordinates LocalCoordsToMap(Vector2 point)
{
if (Viewport == null)
return default;
// pre-scaler
point *= _viewportResolution;
return Viewport.LocalToWorld(point);
}
public MapCoordinates LocalPixelToMap(Vector2 point)
{
if (Viewport == null)
return default;
// pre-scaler
point *= _viewportResolution;
var ev = new PixelToMapEvent(point, this, Viewport);
_entityManager.EventBus.RaiseEvent(EventSource.Local, ref ev);
return Viewport.LocalToWorld(ev.VisiblePosition);
}
public Vector2 WorldToLocalPixel(Vector2 point)
{
if (Viewport?.Eye == null)
return default;
var newPoint = Viewport.WorldToLocal(point);
// pre-scaler
newPoint /= _viewportResolution;
return newPoint;
}
// -- Utils / S2M-M2S Extended --
public MapCoordinates ScreenToMap(Vector2 point)
{
return LocalCoordsToMap(point - GlobalPixelPosition);
}
/// <inheritdoc/>
public MapCoordinates PixelToMap(Vector2 point)
{
return LocalPixelToMap(point - GlobalPixelPosition);
}
public Vector2 WorldToScreen(Vector2 point)
{
return WorldToLocalPixel(point) + GlobalPixelPosition;
}
public Matrix3x2 GetWorldToScreenMatrix()
{
if (Viewport == null)
return Matrix3x2.Identity;
return Viewport.GetWorldToLocalMatrix() * GetLocalToScreenMatrix();
}
public Matrix3x2 GetLocalToScreenMatrix()
{
return Matrix3Helpers.CreateTransform(GlobalPixelPosition, 0, Vector2.One / _viewportResolution);
}
}
}