Three findings from the user's first Configure Keyboard look (OP8 gate, 2026-08-14), each root-caused against the named retail decomp: - #394 row-caption font: the synthesized action-label UiText never set DatFont and fell to the debug bitmap font. The authored row template (0x21000009/0x1000002F, retail UIOption_ActionKeyMap) carries FontDid 0x4000000A (18px serif) — Bind now takes resolveTemplateFont and applies the template's own authored font, resolved once per template pair. - #395 key captions: raw enum spellings ("Shift+ShiftLeft") replaced by the port of CInputManager_WIN32::GetNameFromKey @0x00687F40 / GetNameFromKey_Internal @0x00687800 (RetailKeyNames): DAT string-table override by DIK-name hash (key enum 4 -> 0x2300000A, meta enum 5 -> 0x2300000B, delimiter enum 3 -> 0x23000007 — GetDIDByEnum category 4, live-probed), else the OS keyboard layout's own key name ("SKIFT") via PlatformKeyNameProvider (Win32 GetKeyNameTextW — register row AD-96 for the DirectInput-vs-GetKeyNameText adaptation), else the DIK-suffix spelling. Bare modifier-key bindings show only the key name. - #396 capture feedback: clicking a mapping button now opens retail's instruction dialog (InitiateBinding @0x004899D0 -> OpenMapWarnDialog @0x00488A00): a type-2 WAIT dialog on retail's MapWarn queue key 0x10000001 with ID_ActionKeyMap_MapInstructions (0x23000004, ACTION variable interpolated), closed on key hit or ESC through the capture callback; capture is not armed if the dialog cannot open, matching retail. New RetailWaitDialogView (wait root 0x31 — same authored popup/message pair 0x3D/0x3E as the confirmation root, live-DAT probed) behind a shared IRetailDialogView presenter seam. Probe evidence (env-gated, kept): KeyboardConfigLiveMountProbeTests.ProbeKeyboardFontsAndKeyNameStrings. Register: AD-96 filed. Gate script OP8 section updated (step 4 rewritten; the "pressed/active state is enough" contract is retired). Full Release solution suite green (13,424 passed / 4 skips). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1528e5693b
commit
30fa6ee507
16 changed files with 1105 additions and 24 deletions
|
|
@ -16,7 +16,7 @@ public sealed class RetailDialogFactory : IDisposable
|
|||
public required uint Context { get; init; }
|
||||
public required uint QueueKey { get; init; }
|
||||
public Action<RetailDialogData>? Callback { get; init; }
|
||||
public RetailConfirmationDialogView? View { get; set; }
|
||||
public IRetailDialogView? View { get; set; }
|
||||
}
|
||||
|
||||
private readonly UiRoot _host;
|
||||
|
|
@ -135,6 +135,19 @@ public sealed class RetailDialogFactory : IDisposable
|
|||
return MakeDialog(data, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Text-only wait dialog (type 2), closed by the caller via
|
||||
/// <see cref="CloseDialog"/>. Property shape mirrors
|
||||
/// <c>UIOption_ActionKeyMap::OpenMapWarnDialog @ 0x00488A00</c>: type 2,
|
||||
/// caller-chosen queue key, element attribute 0x40 set, message text.
|
||||
/// </summary>
|
||||
public uint MakeWait(string message, uint queueKey = DefaultQueueKey)
|
||||
{
|
||||
RetailDialogData data = RetailDialogData.Wait(message)
|
||||
.Set(RetailDialogProperty.QueueKey, queueKey);
|
||||
return MakeDialog(data, callback: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>CloseDialog @ 0x00478160</c>. The context can identify an active
|
||||
/// nonqueued dialog, an active queued dialog, or an item still pending in a queue.
|
||||
|
|
@ -262,16 +275,20 @@ public sealed class RetailDialogFactory : IDisposable
|
|||
private void CreateDialog(DialogInfo info)
|
||||
{
|
||||
RetailDialogType type = (RetailDialogType)info.Data.GetUInt32(RetailDialogProperty.Type);
|
||||
if (type != RetailDialogType.Confirmation)
|
||||
if (type is not (RetailDialogType.Confirmation or RetailDialogType.Wait))
|
||||
throw new NotSupportedException(
|
||||
$"Retail dialog type {(uint)type} does not have a ported presenter yet.");
|
||||
|
||||
ImportedLayout layout = _createLayout(type)
|
||||
?? throw new InvalidOperationException(
|
||||
$"Retail dialog catalog could not create type {(uint)type}.");
|
||||
var view = new RetailConfirmationDialogView(
|
||||
_host, layout, info.Data, info.Context,
|
||||
context => CloseDialog(context));
|
||||
IRetailDialogView view = type switch
|
||||
{
|
||||
RetailDialogType.Wait => new RetailWaitDialogView(_host, layout, info.Data),
|
||||
_ => new RetailConfirmationDialogView(
|
||||
_host, layout, info.Data, info.Context,
|
||||
context => CloseDialog(context)),
|
||||
};
|
||||
info.View = view;
|
||||
_host.AddChild(view.Root);
|
||||
_host.BringToFront(view.Root);
|
||||
|
|
@ -285,7 +302,7 @@ public sealed class RetailDialogFactory : IDisposable
|
|||
{
|
||||
if (info.View is null)
|
||||
return;
|
||||
RetailConfirmationDialogView view = info.View;
|
||||
IRetailDialogView view = info.View;
|
||||
info.View = null;
|
||||
view.DetachHandlers();
|
||||
_openOrder.Remove(info);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue