feat(ui): persist retained window layouts
This commit is contained in:
parent
a8e9503d2e
commit
921c388e2c
22 changed files with 705 additions and 141 deletions
|
|
@ -24,7 +24,7 @@ namespace AcDream.App.UI.Layout;
|
|||
/// and bound in place.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public sealed class ChatWindowController
|
||||
public sealed class ChatWindowController : IRetainedWindowStateController
|
||||
{
|
||||
public const uint LayoutId = 0x21000006u;
|
||||
|
||||
|
|
@ -364,13 +364,16 @@ public sealed class ChatWindowController
|
|||
_normalHeight = frame.Height;
|
||||
|
||||
float expansion = parentHeight / 2f;
|
||||
float targetTop = frame.Top;
|
||||
float targetHeight = frame.Height + expansion;
|
||||
if (frame.Top + targetHeight > parentHeight || frame.Top >= parentHeight / 2f)
|
||||
targetTop = MathF.Max(0f, frame.Top - expansion);
|
||||
|
||||
float targetHeight = Math.Clamp(
|
||||
MathF.Min(frame.Height + expansion, parentHeight),
|
||||
frame.MinHeight,
|
||||
frame.MaxHeight);
|
||||
bool growUp = frame.Top + targetHeight > parentHeight
|
||||
|| frame.Top >= parentHeight / 2f;
|
||||
float targetTop = growUp
|
||||
? MathF.Max(0f, frame.Top - (targetHeight - frame.Height))
|
||||
: frame.Top;
|
||||
targetHeight = MathF.Min(targetHeight, parentHeight - targetTop);
|
||||
targetHeight = Math.Clamp(targetHeight, frame.MinHeight, frame.MaxHeight);
|
||||
|
||||
_maximized = true;
|
||||
_maxMinButton?.TrySetRetailState(RetailUiStateIds.Maximized);
|
||||
|
|
@ -378,6 +381,21 @@ public sealed class ChatWindowController
|
|||
handle.MoveTo(frame.Left, targetTop);
|
||||
}
|
||||
|
||||
public RetainedWindowState CaptureWindowState()
|
||||
=> new(
|
||||
Maximized: _maximized,
|
||||
PersistedTop: _maximized ? _normalTop : null,
|
||||
PersistedHeight: _maximized ? _normalHeight : null);
|
||||
|
||||
public void RestoreWindowState(RetainedWindowState state)
|
||||
{
|
||||
if (state.Maximized != _maximized)
|
||||
ToggleMaximize();
|
||||
else
|
||||
_maxMinButton?.TrySetRetailState(
|
||||
_maximized ? RetailUiStateIds.Maximized : RetailUiStateIds.Minimized);
|
||||
}
|
||||
|
||||
private static ElementInfo? FindInfo(ElementInfo node, uint id)
|
||||
{
|
||||
if (node.Id == id) return node;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ public sealed class InventoryController : IItemListDragHandler
|
|||
public const uint ContentsCaptionId = 0x100001C5u; // "Contents of Backpack"
|
||||
public const uint TitleTextId = 0x100001D3u; // "Inventory of <name>"
|
||||
public const uint ContentsScrollbarId = 0x100001C7u; // gm3DItemsUI gutter scrollbar (right of the grid)
|
||||
private const uint BackdropId = 0x100001D0u;
|
||||
private const uint ContentsWindowId = 0x100001CFu;
|
||||
private const uint PaperdollWindowId = 0x100001CDu;
|
||||
private const uint BackpackWindowId = 0x100001CEu;
|
||||
|
||||
// 3D-items grid: 192x96 → 6 cols x 3 rows of the 32x32 UIItem cell (template 0x21000037).
|
||||
private const int ContentsColumns = 6;
|
||||
|
|
@ -92,6 +96,8 @@ public sealed class InventoryController : IItemListDragHandler
|
|||
_containerList = layout.FindElement(ContainerListId) as UiItemList;
|
||||
_topContainer = layout.FindElement(TopContainerId) as UiItemList;
|
||||
|
||||
ConfigureResizeLayout(layout);
|
||||
|
||||
if (_contentsGrid is not null)
|
||||
{
|
||||
_contentsGrid.Columns = ContentsColumns;
|
||||
|
|
@ -153,6 +159,24 @@ public sealed class InventoryController : IItemListDragHandler
|
|||
Populate();
|
||||
}
|
||||
|
||||
internal static void ConfigureResizeLayout(ImportedLayout layout)
|
||||
{
|
||||
static void Set(ImportedLayout imported, uint id, AnchorEdges anchors)
|
||||
{
|
||||
if (imported.FindElement(id) is not { } element) return;
|
||||
element.Anchors = anchors;
|
||||
element.CaptureCurrentAnchorBaseline();
|
||||
}
|
||||
|
||||
AnchorEdges stretch = AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Bottom;
|
||||
Set(layout, BackdropId, stretch);
|
||||
Set(layout, ContentsWindowId, stretch);
|
||||
Set(layout, ContentsGridId, stretch);
|
||||
Set(layout, ContentsScrollbarId, stretch);
|
||||
Set(layout, PaperdollWindowId, AnchorEdges.Left | AnchorEdges.Top);
|
||||
Set(layout, BackpackWindowId, AnchorEdges.Left | AnchorEdges.Top);
|
||||
}
|
||||
|
||||
public static InventoryController Bind(
|
||||
ImportedLayout layout,
|
||||
ClientObjectTable objects,
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public static class RetailWindowFrame
|
|||
AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Right | AnchorEdges.Bottom;
|
||||
public bool? ContentClickThrough { get; init; }
|
||||
public IRetainedPanelController? Controller { get; init; }
|
||||
public IRetainedWindowStateController? StateController { get; init; }
|
||||
}
|
||||
|
||||
public static RetailWindowHandle Mount(
|
||||
|
|
@ -159,7 +160,8 @@ public static class RetailWindowFrame
|
|||
options.WindowName,
|
||||
outerFrame,
|
||||
content,
|
||||
options.Controller);
|
||||
options.Controller,
|
||||
options.StateController);
|
||||
}
|
||||
|
||||
private static float ResolveConstraint(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue