fix(ui): restore retail vitals and window interactions
This commit is contained in:
parent
4d84456c21
commit
1bd2b30291
36 changed files with 1462 additions and 86 deletions
|
|
@ -1,6 +1,8 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.UI;
|
||||
using AcDream.App.UI.Layout;
|
||||
using AcDream.App.Rendering;
|
||||
using AcDream.App.Tests.Rendering.Gpu;
|
||||
using AcDream.Core.Ui;
|
||||
|
||||
namespace AcDream.App.Tests.UI.Layout;
|
||||
|
|
@ -101,6 +103,111 @@ public sealed class RadarControllerTests
|
|||
Assert.False(layout.FindElement(RadarController.CoordinateContainerId)!.Visible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Bind_RealFixture_RootPointerLockCycleRoundTripsAuthorityAndMedia()
|
||||
{
|
||||
var layout = LayoutImporter.Build(
|
||||
FixtureLoader.LoadRadarInfos(),
|
||||
static file => (file, 8, 8),
|
||||
null);
|
||||
var root = new UiRoot { Width = 800, Height = 600 };
|
||||
root.AddChild(layout.Root);
|
||||
var state = UiRadarSnapshot.Empty with { UiLocked = false };
|
||||
var requestedLocks = new List<bool>();
|
||||
using var controller = RadarController.Bind(
|
||||
layout,
|
||||
() => state,
|
||||
setUiLocked: value =>
|
||||
{
|
||||
// Production's corrected contract: update the authoritative
|
||||
// character option before pushing the retained-root message.
|
||||
requestedLocks.Add(value);
|
||||
state = state with { UiLocked = value };
|
||||
root.UiLocked = value;
|
||||
});
|
||||
|
||||
var radar = Assert.IsType<UiRadar>(layout.Root);
|
||||
var lockButton = Assert.IsType<UiButton>(
|
||||
layout.FindElement(RadarController.LockButtonId));
|
||||
var dragButton = Assert.IsType<UiDatElement>(
|
||||
layout.FindElement(RadarController.DragButtonId));
|
||||
|
||||
radar.Refresh();
|
||||
Assert.Equal("UnlockedUI", lockButton.ActiveState);
|
||||
Assert.Equal(0x060074B8u, DrawnFaceFile(lockButton));
|
||||
Assert.True(lockButton.Visible);
|
||||
Assert.False(lockButton.ClickThrough);
|
||||
Assert.True(dragButton.Visible);
|
||||
Assert.True(radar.Draggable);
|
||||
|
||||
ClickThroughRoot(root, lockButton);
|
||||
radar.Refresh();
|
||||
|
||||
Assert.Equal([true], requestedLocks);
|
||||
Assert.True(root.UiLocked);
|
||||
Assert.Equal("LockedUI", lockButton.ActiveState);
|
||||
Assert.Equal(0x060074B7u, DrawnFaceFile(lockButton));
|
||||
Assert.True(lockButton.Visible);
|
||||
Assert.False(lockButton.ClickThrough);
|
||||
Assert.False(dragButton.Visible);
|
||||
Assert.False(radar.Draggable);
|
||||
|
||||
MoveAwayAndBack(root, lockButton);
|
||||
Assert.Equal("LockedUI", lockButton.ActiveState);
|
||||
Assert.Equal(0x060074B7u, DrawnFaceFile(lockButton));
|
||||
|
||||
// UiLocked suppresses move/resize only. The same radar button remains
|
||||
// hit-testable and must be able to publish the authoritative unlock.
|
||||
ClickThroughRoot(root, lockButton);
|
||||
radar.Refresh();
|
||||
|
||||
Assert.Equal([true, false], requestedLocks);
|
||||
Assert.False(root.UiLocked);
|
||||
Assert.Equal("UnlockedUI", lockButton.ActiveState);
|
||||
Assert.Equal(0x060074B8u, DrawnFaceFile(lockButton));
|
||||
Assert.True(lockButton.Visible);
|
||||
Assert.False(lockButton.ClickThrough);
|
||||
Assert.True(dragButton.Visible);
|
||||
Assert.True(radar.Draggable);
|
||||
|
||||
MoveAwayAndBack(root, lockButton);
|
||||
Assert.Equal("UnlockedUI", lockButton.ActiveState);
|
||||
Assert.Equal(0x060074B8u, DrawnFaceFile(lockButton));
|
||||
}
|
||||
|
||||
private static void ClickThroughRoot(UiRoot root, UiButton button)
|
||||
{
|
||||
Vector2 position = button.ScreenPosition;
|
||||
int x = (int)(position.X + button.Width * 0.5f);
|
||||
int y = (int)(position.Y + button.Height * 0.5f);
|
||||
root.OnMouseMove(x, y);
|
||||
root.OnMouseDown(UiMouseButton.Left, x, y);
|
||||
root.OnMouseUp(UiMouseButton.Left, x, y);
|
||||
}
|
||||
|
||||
private static void MoveAwayAndBack(UiRoot root, UiButton button)
|
||||
{
|
||||
root.OnMouseMove(700, 500);
|
||||
Vector2 position = button.ScreenPosition;
|
||||
root.OnMouseMove(
|
||||
(int)(position.X + button.Width * 0.5f),
|
||||
(int)(position.Y + button.Height * 0.5f));
|
||||
}
|
||||
|
||||
private static uint DrawnFaceFile(UiButton button)
|
||||
{
|
||||
var renderer = new TextRenderer(
|
||||
new RecordingGpuDevice(), new NullGpuFrameSource(), "unused");
|
||||
renderer.Begin(new Vector2(200f, 200f));
|
||||
button.DrawSelfAndChildren(new UiRenderContext(renderer, new Vector2(200f, 200f)));
|
||||
return Assert.Single(renderer.DebugSpriteSegments).Texture;
|
||||
}
|
||||
|
||||
private sealed class NullGpuFrameSource : ICurrentGpuFrameSource
|
||||
{
|
||||
public AcDream.App.Rendering.Gpu.IGpuFrame? CurrentFrame => null;
|
||||
}
|
||||
|
||||
private static ImportedLayout BuildRadarLayout()
|
||||
{
|
||||
var root = new ElementInfo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue