using AcDream.App.UI; using AcDream.App.UI.Layout; namespace AcDream.App.Tests.UI.Layout; public sealed class RetailWindowFrameTests { private static (uint, int, int) NoTex(uint _) => (0u, 0, 0); [Fact] public void ImportedChrome_MountsRootWithoutASecondFrame() { var root = new UiRoot { Width = 800, Height = 600 }; var content = new UiPanel { Width = 220, Height = 90 }; RetailWindowHandle handle = RetailWindowFrame.Mount( root, content, NoTex, new RetailWindowFrame.Options { WindowName = "vitals", Chrome = RetailWindowChrome.Imported, Left = 12, Top = 18, ResizeX = true, ResizeY = false, MinWidth = 40, ContentClickThrough = false, }); Assert.Same(content, handle.OuterFrame); Assert.Same(content, handle.ContentRoot); Assert.Same(root, content.Parent); Assert.Equal((12f, 18f, 220f, 90f), (content.Left, content.Top, content.Width, content.Height)); Assert.True(content.Draggable); Assert.True(content.Resizable); Assert.True(content.ResizeX); Assert.False(content.ResizeY); Assert.Equal(40f, content.MinWidth); } [Fact] public void NineSlice_UsesCroppedContentAndDatHeightConstraints() { var root = new UiRoot { Width = 800, Height = 600 }; var content = new UiPanel { Width = 800, Height = 100 }; var constraints = Constraints(minHeight: 100, maxHeight: 360); RetailWindowHandle handle = RetailWindowFrame.Mount( root, content, NoTex, new RetailWindowFrame.Options { WindowName = "chat", Chrome = RetailWindowChrome.NineSlice, Left = 10, Top = 440, ContentWidth = 490, DatConstraintSource = constraints, MinWidth = 200, Opacity = 0.75f, }); var frame = Assert.IsType(handle.OuterFrame); Assert.Same(content, handle.ContentRoot); Assert.Same(frame, content.Parent); Assert.Equal((500f, 110f), (frame.Width, frame.Height)); Assert.Equal((5f, 5f, 490f, 100f), (content.Left, content.Top, content.Width, content.Height)); Assert.Equal(200f, frame.MinWidth); Assert.Equal(110f, frame.MinHeight); Assert.Equal(370f, frame.MaxHeight); Assert.Equal(0.75f, frame.Opacity); } [Fact] public void CollapsibleMount_ReturnsToolbarFrameAndIndependentAxes() { var root = new UiRoot { Width = 800, Height = 600 }; var content = new UiPanel { Width = 300, Height = 122 }; RetailWindowHandle handle = RetailWindowFrame.Mount( root, content, NoTex, new RetailWindowFrame.Options { WindowName = "toolbar", Chrome = RetailWindowChrome.CollapsibleNineSlice, ResizeX = false, ResizeY = true, ResizableEdges = ResizeEdges.Bottom, ContentAnchors = AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Right, ContentClickThrough = true, }); var frame = Assert.IsType(handle.OuterFrame); Assert.False(frame.ResizeX); Assert.True(frame.ResizeY); Assert.Equal(ResizeEdges.Bottom, frame.ResizableEdges); Assert.True(content.ClickThrough); Assert.False(content.Draggable); Assert.False(content.Resizable); } [Fact] public void HiddenInventory_RestoredExpandedBeforeFirstDraw_GrowsContentsRows() { ImportedLayout layout = FixtureLoader.LoadInventory(); UiItemList grid = Assert.IsType( layout.FindElement(InventoryController.ContentsGridId)); grid.Columns = 6; grid.CellWidth = 32f; grid.CellHeight = 32f; grid.Flush(); for (int i = 0; i < 102; i++) grid.AddItem(new UiItemSlot()); var root = new UiRoot { Width = 1280, Height = 720 }; RetailWindowHandle handle = RetailWindowFrame.Mount( root, layout.Root, NoTex, new RetailWindowFrame.Options { WindowName = WindowNames.Inventory, Chrome = RetailWindowChrome.NineSlice, ContentWidth = layout.Root.Width, ContentHeight = layout.Root.Height, Visible = false, ResizeX = false, ResizeY = true, ResizableEdges = ResizeEdges.Bottom, MaxHeight = 560f, }); // Production installs the controller-owned policies after mounting, while // inventory is still hidden, and captures their design baseline immediately. InventoryController.ConfigureResizeLayout(layout); // Persistence restores the hidden window before its first visible draw. handle.ResizeTo(handle.Width, 527f); ApplyAnchors(handle.OuterFrame); grid.LayoutCells(); Assert.Equal(251f, grid.Height); Assert.Equal(48, grid.Children.Count(child => child.Visible)); Assert.Equal(224f, grid.GetItem(42)!.Top); // final row intersects 251px view by 27px } private static void ApplyAnchors(UiElement parent) { foreach (UiElement child in parent.Children) { child.ApplyAnchor(parent.Width, parent.Height); ApplyAnchors(child); } } private static ElementInfo Constraints(int minHeight, int maxHeight) { var info = new ElementInfo(); var direct = new UiStateInfo { Id = UiStateInfo.DirectStateId }; direct.Properties.Values[0x3Eu] = new UiPropertyValue { Kind = UiPropertyKind.Integer, IntegerValue = minHeight, }; direct.Properties.Values[0x3Cu] = new UiPropertyValue { Kind = UiPropertyKind.Integer, IntegerValue = maxHeight, }; info.States[UiStateInfo.DirectStateId] = direct; return info; } }