fix(ui): preserve cropped chat and button faces

This commit is contained in:
Erik 2026-07-10 18:11:14 +02:00
parent d825572e31
commit accacecafe
7 changed files with 168 additions and 8 deletions

View file

@ -1,5 +1,8 @@
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Chat;
using AcDream.UI.Abstractions;
using AcDream.UI.Abstractions.Panels.Chat;
namespace AcDream.App.Tests.UI.Layout;
@ -10,6 +13,8 @@ namespace AcDream.App.Tests.UI.Layout;
/// </summary>
public class ChatLayoutConformanceTests
{
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
private static ElementInfo? Find(ElementInfo n, uint id)
{
if (n.Id == id) return n;
@ -58,4 +63,58 @@ public class ChatLayoutConformanceTests
Assert.True(input.OneLine);
Assert.Equal(0x10000016u, input.DatElementId);
}
[Fact]
public void ChatFixture_CroppedDockedRoot_ReflowsContentAcrossMountedWidth()
{
var infos = FixtureLoader.LoadChatInfos();
var layout = LayoutImporter.Build(infos, NoTex, null);
var controller = ChatWindowController.Bind(
infos,
layout,
new ChatVM(new ChatLog()),
() => NullCommandBus.Instance,
null,
null,
NoTex);
Assert.NotNull(controller);
var root = controller!.Root;
root.Width = 490;
root.Height = 100;
root.RebaseChildLayoutBaselines();
root.Width = 615;
var transcriptPanel = layout.FindElement(0x10000010u)!;
var inputBar = layout.FindElement(0x10000013u)!;
transcriptPanel.ApplyAnchor(root.Width, root.Height);
inputBar.ApplyAnchor(root.Width, root.Height);
Assert.Equal(615f, transcriptPanel.Width);
Assert.Equal(615f, inputBar.Width);
}
[Fact]
public void ChatFixture_ChannelCaptionWidth_SurvivesImportedLayoutPass()
{
var infos = FixtureLoader.LoadChatInfos();
var layout = LayoutImporter.Build(infos, NoTex, null);
var controller = ChatWindowController.Bind(
infos,
layout,
new ChatVM(new ChatLog()),
() => NullCommandBus.Instance,
null,
null,
NoTex);
Assert.NotNull(controller);
controller!.Menu.OnSelect!.Invoke(ChatChannelKind.General);
float fittedWidth = controller.Menu.Width;
controller.Menu.ApplyAnchor(controller.Menu.Parent!.Width, controller.Menu.Parent.Height);
Assert.True(fittedWidth > 46f);
Assert.Equal(fittedWidth, controller.Menu.Width);
Assert.Equal(controller.Menu.Left + fittedWidth, controller.Input.Left);
}
}

View file

@ -86,6 +86,22 @@ public class UiButtonTests
Assert.Equal("LockedUI", b.ActiveState);
}
[Fact]
public void PropertyOnlyPressedState_PreservesDrawableNormalFace()
{
var info = ButtonInfo("Normal", "Highlight");
info.States[UiButtonStateMachine.NormalPressed] = new UiStateInfo
{
Id = UiButtonStateMachine.NormalPressed,
Name = "Normal_pressed",
};
var b = CreateButton(info);
b.OnEvent(new UiEvent(0, b, UiEventType.MouseDown, Data1: 5, Data2: 5));
Assert.Equal("Normal", b.ActiveState);
}
[Fact]
public void HotClick_FiresImmediatelyRepeatsAndSuppressesReleaseClick()
{

View file

@ -129,4 +129,50 @@ public sealed class UiLayoutPolicyTests
Assert.Equal(400f, element.Width);
Assert.Equal(200f, element.Height);
}
[Fact]
public void ResetAnchorCapture_RebasesImportedPolicyAfterControllerResize()
{
var parent = new UiPanel { Width = 490, Height = 17 };
var child = new UiPanel
{
Left = 0,
Top = 0,
Width = 46,
Height = 17,
LayoutPolicy = new UiLayoutPolicy(
1, 1, 2, 1,
UiPixelRect.FromPositionAndSize(0, 0, 46, 17),
UiPixelRect.FromPositionAndSize(0, 0, 490, 17)),
};
parent.AddChild(child);
child.Width = 72;
child.ResetAnchorCapture();
child.ApplyAnchor(parent.Width, parent.Height);
Assert.Equal(72f, child.Width);
}
[Fact]
public void RebaseChildLayoutBaselines_CroppedChatRegionThenGrowsWithFrame()
{
var root = new UiPanel { Width = 490, Height = 100 };
var transcriptPanel = new UiPanel
{
Width = 490,
Height = 83,
LayoutPolicy = new UiLayoutPolicy(
1, 1, 1, 1,
UiPixelRect.FromPositionAndSize(0, 0, 490, 83),
UiPixelRect.FromPositionAndSize(0, 0, 800, 100)),
};
root.AddChild(transcriptPanel);
root.RebaseChildLayoutBaselines();
root.Width = 615;
transcriptPanel.ApplyAnchor(root.Width, root.Height);
Assert.Equal(615f, transcriptPanel.Width);
}
}