feat(ui): port retained widget foundations

This commit is contained in:
Erik 2026-07-10 17:55:41 +02:00
parent 44f9ec13d9
commit d825572e31
44 changed files with 84813 additions and 292 deletions

View file

@ -27,6 +27,9 @@ public static class VitalsController
public const uint Stamina = 0x100000EC;
/// <summary>Dat element id for the Mana meter (0x100000EE).</summary>
public const uint Mana = 0x100000EE;
public const uint HealthText = 0x100000EB;
public const uint StaminaText = 0x100000ED;
public const uint ManaText = 0x100000EF;
/// <summary>
/// Bind live vitals data providers to the Health, Stamina, and Mana meter
@ -50,16 +53,16 @@ public static class VitalsController
Func<string> staminaText,
Func<string> manaText)
{
BindMeter(layout, Health, healthPct, healthText);
BindMeter(layout, Stamina, staminaPct, staminaText);
BindMeter(layout, Mana, manaPct, manaText);
BindMeter(layout, Health, HealthText, healthPct, healthText);
BindMeter(layout, Stamina, StaminaText, staminaPct, staminaText);
BindMeter(layout, Mana, ManaText, manaPct, manaText);
}
/// <summary>White cur/max numbers — matches the former <c>UiMeter.LabelColor</c> default.</summary>
private static readonly Vector4 NumberColor = new(1f, 1f, 1f, 1f);
private static void BindMeter(
ImportedLayout layout, uint id,
ImportedLayout layout, uint id, uint textId,
Func<float> pct,
Func<string> text)
{
@ -68,31 +71,22 @@ public static class VitalsController
m.Fill = () => pct();
// Retail gmVitalsUI renders the cur/max as a real UIElement_Text centered over the
// bar — NOT a meter-internal label. Attach a centered UiText (non-interactive
// decoration) that fills + stretches with the meter, and stop the meter drawing its
// own label. UiText.Centered uses the SAME centering formula the meter's overlay did,
// so the numbers stay pixel-identical (locked by the visual gate).
// Retail gmVitalsUI binds the authored UIElement_Text over each meter. The
// importer already built and registered that node; do not synthesize a duplicate.
m.Label = () => null;
if (layout.FindElement(textId) is not UiText number) return;
var number = new UiText
number.Centered = true;
number.RightAligned = false;
number.OneLine = true;
number.Selectable = false;
number.DatFont ??= m.DatFont;
number.LinesProvider = () =>
{
Left = 0f, Top = 0f, Width = m.Width, Height = m.Height,
Anchors = AnchorEdges.Left | AnchorEdges.Top | AnchorEdges.Right | AnchorEdges.Bottom,
Centered = true,
DatFont = m.DatFont, // the same dat font the meter used for its label
ClickThrough = true, // decoration: no focus / selection / drag
AcceptsFocus = false,
IsEditControl = false,
CapturesPointerDrag = false,
LinesProvider = () =>
{
var s = text();
return string.IsNullOrEmpty(s)
? Array.Empty<UiText.Line>()
: new[] { new UiText.Line(s, NumberColor) };
},
var s = text();
return string.IsNullOrEmpty(s)
? Array.Empty<UiText.Line>()
: new[] { new UiText.Line(s, NumberColor) };
};
m.AddChild(number);
}
}