using Friflo.Engine.ECS.Systems;
using Microsoft.Xna.Framework;
using MrGameEng.Core;
using Myra;
using Myra.Graphics2D.UI;
namespace MrGameEng.UI;
///
/// Draw system rendering the scene's Myra . Must run after the scene's
/// world rendering (register UI last in the draw phase) — the UI is drawn on top in window
/// pixels and also processes mouse/keyboard interaction during render. While
/// is set (developer console open), the desktop is drawn
/// without processing input, so overlay clicks and keystrokes do not fall through to it.
///
public sealed class UiRenderSystem : BaseSystem
{
private readonly Desktop _desktop;
private readonly InputCapture? _capture;
/// Creates the system for .
public UiRenderSystem(Desktop desktop, InputCapture? capture = null)
{
_desktop = desktop;
_capture = capture;
}
///
protected override void OnUpdateGroup()
{
if (_capture?.Captured == true)
{
// Render() = UpdateInput + UpdateLayout + RenderVisual; пропускаем только ввод.
_desktop.UpdateLayout();
_desktop.RenderVisual();
}
else
{
_desktop.Render();
}
}
}
/// Wires the UI module (Myra) into a .
public static class SceneUiExtensions
{
///
/// Creates a Myra for this scene and registers
/// in the draw phase. Call from OnLoad
/// after UseRenderer2D() so the UI draws on top of the world.
/// Build the UI by assigning . The desktop is disposed
/// automatically when the scene unloads.
///
public static Desktop UseUI(this Scene scene)
{
var services = scene.Context.Services;
// Присваивание идемпотентно; геттер MyraEnvironment.Game бросает исключение, пока
// Game не задан, поэтому проверять текущее значение перед записью нельзя.
MyraEnvironment.Game = services.Get();
var capture = services.GetOrDefault();
if (capture is null)
{
capture = new InputCapture();
services.Add(capture);
}
var desktop = new Desktop();
scene.RegisterUnload(desktop.Dispose);
scene.DrawSystems.Add(new UiRenderSystem(desktop, capture));
return desktop;
}
}