feat(ui): persist retained window layouts
This commit is contained in:
parent
a8e9503d2e
commit
921c388e2c
22 changed files with 705 additions and 141 deletions
102
tests/AcDream.App.Tests/UI/RetailWindowLayoutPersistenceTests.cs
Normal file
102
tests/AcDream.App.Tests/UI/RetailWindowLayoutPersistenceTests.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using AcDream.App.UI;
|
||||
using AcDream.UI.Abstractions.Panels.Settings;
|
||||
|
||||
namespace AcDream.App.Tests.UI;
|
||||
|
||||
public sealed class RetailWindowLayoutPersistenceTests : IDisposable
|
||||
{
|
||||
private readonly string _directory = Path.Combine(
|
||||
Path.GetTempPath(), "acdream-window-layout-tests-" + Guid.NewGuid().ToString("N"));
|
||||
private string PathName => Path.Combine(_directory, "settings.json");
|
||||
|
||||
[Fact]
|
||||
public void CompletedInteractions_SaveCompleteCharacterResolutionLayout()
|
||||
{
|
||||
var store = new SettingsStore(PathName);
|
||||
var root = new UiRoot { Width = 800, Height = 600 };
|
||||
RetailWindowHandle handle = Mount(root, "chat");
|
||||
using var persistence = new RetailWindowLayoutPersistence(
|
||||
root.WindowManager, store, () => "Alice", () => (800, 600));
|
||||
|
||||
handle.MoveTo(44f, 55f);
|
||||
handle.ResizeTo(320f, 180f);
|
||||
handle.Hide();
|
||||
|
||||
UiWindowLayout saved = Assert.IsType<UiWindowLayout>(
|
||||
store.LoadWindowLayout("Alice", "800x600", "chat", default));
|
||||
Assert.Equal((44f, 55f, 320f, 180f), (saved.X, saved.Y, saved.Width, saved.Height));
|
||||
Assert.False(saved.Visible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Restore_ClampsBoundsAndReappliesPanelStateAndVisibility()
|
||||
{
|
||||
var store = new SettingsStore(PathName);
|
||||
store.SaveWindowLayout(
|
||||
"Alice",
|
||||
"640x480",
|
||||
"chat",
|
||||
new UiWindowLayout(900f, 700f, 500f, 300f, false, false, true));
|
||||
|
||||
var root = new UiRoot { Width = 640, Height = 480 };
|
||||
var state = new FakeWindowState();
|
||||
RetailWindowHandle handle = Mount(root, "chat", state);
|
||||
using var persistence = new RetailWindowLayoutPersistence(
|
||||
root.WindowManager, store, () => "Alice", () => (640, 480));
|
||||
|
||||
persistence.RestoreAll();
|
||||
|
||||
Assert.Equal((500f, 300f), (handle.Width, handle.Height));
|
||||
Assert.Equal((140f, 180f), (handle.Left, handle.Top));
|
||||
Assert.False(handle.IsVisible);
|
||||
Assert.True(state.Restored.Maximized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultPreLoginKey_NeverOverwritesCharacterLayouts()
|
||||
{
|
||||
var store = new SettingsStore(PathName);
|
||||
var root = new UiRoot { Width = 800, Height = 600 };
|
||||
RetailWindowHandle handle = Mount(root, "radar");
|
||||
using var persistence = new RetailWindowLayoutPersistence(
|
||||
root.WindowManager, store, () => "default", () => (800, 600));
|
||||
|
||||
handle.MoveTo(123f, 234f);
|
||||
|
||||
Assert.Null(store.LoadWindowLayout("default", "800x600", "radar", default));
|
||||
}
|
||||
|
||||
private static RetailWindowHandle Mount(
|
||||
UiRoot root,
|
||||
string name,
|
||||
IRetainedWindowStateController? state = null)
|
||||
{
|
||||
var frame = new UiPanel
|
||||
{
|
||||
Left = 10f,
|
||||
Top = 20f,
|
||||
Width = 200f,
|
||||
Height = 100f,
|
||||
MinWidth = 100f,
|
||||
MinHeight = 80f,
|
||||
MaxWidth = 600f,
|
||||
MaxHeight = 400f,
|
||||
Draggable = true,
|
||||
Resizable = true,
|
||||
};
|
||||
root.AddChild(frame);
|
||||
return root.RegisterWindow(name, frame, stateController: state);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true);
|
||||
}
|
||||
|
||||
private sealed class FakeWindowState : IRetainedWindowStateController
|
||||
{
|
||||
public RetainedWindowState Restored { get; private set; }
|
||||
public RetainedWindowState CaptureWindowState() => Restored;
|
||||
public void RestoreWindowState(RetainedWindowState state) => Restored = state;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue