Introduces UiButton: a dedicated dat-widget button that ports UIElement_Button (RegisterElementClass(1,...) @ acclient_2013_pseudo_c.txt:125828). State selection, tiled DrawSprite, and label rendering mirror UiDatElement exactly so the chat Send and Max/Min buttons have zero behavioral change. DatWidgetFactory now maps Type 1 → UiButton (beside Type 7 → UiMeter, Type 11 → UiScrollbar). ChatWindowController's Send and Max/Min bind blocks updated from UiDatElement casts to UiButton casts; ClickThrough=false lines dropped (UiButton is interactive by construction). The old UiPanel.cs UiButton (a plain dev-scaffold rect+text button with no dat sprites) is renamed UiSimpleButton to free the name — no production code instantiated it. Full suite: 402 passed, 2 skipped, 0 failed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
3.4 KiB
C#
96 lines
3.4 KiB
C#
using System.Numerics;
|
|
|
|
namespace AcDream.App.UI;
|
|
|
|
/// <summary>
|
|
/// Rectangular container with an optional translucent background and
|
|
/// border. Used as the base of every retail panel (attributes, chat,
|
|
/// inventory, login, etc.).
|
|
///
|
|
/// Retail has panel background art stored as 9-slice sprite assets in
|
|
/// the <c>0x06xxxxxx</c> RenderSurface range, and composed via
|
|
/// <c>LayoutDesc</c> (<c>0x21xxxxxx</c>) trees. Until our
|
|
/// <c>AcFont</c>/<c>UiSpriteBatch</c> consumes those directly, we draw a
|
|
/// simple translucent rectangle so panels are visible during development.
|
|
/// </summary>
|
|
public class UiPanel : UiElement
|
|
{
|
|
/// <summary>Background fill color. Set <see cref="Vector4.Zero"/> to skip.</summary>
|
|
public Vector4 BackgroundColor { get; set; } = new(0f, 0f, 0f, 0.55f);
|
|
|
|
/// <summary>Border color. Set <see cref="Vector4.Zero"/> to skip.</summary>
|
|
public Vector4 BorderColor { get; set; } = new(0.15f, 0.15f, 0.2f, 0.8f);
|
|
|
|
public float BorderThickness { get; set; } = 1f;
|
|
|
|
protected override void OnDraw(UiRenderContext ctx)
|
|
{
|
|
if (BackgroundColor.W > 0f)
|
|
ctx.DrawRect(0, 0, Width, Height, BackgroundColor);
|
|
|
|
if (BorderColor.W > 0f && BorderThickness > 0f)
|
|
ctx.DrawRectOutline(0, 0, Width, Height, BorderColor, BorderThickness);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Static text label. Draws a single line of text using the context's
|
|
/// default font (or an override). Does not consume input.
|
|
///
|
|
/// Equivalent retail primitive: wide-string appended to a CString via
|
|
/// <c>FUN_0040b8f0</c> then drawn by the widget's draw method through
|
|
/// <c>FUN_00698330</c>.
|
|
/// </summary>
|
|
public class UiLabel : UiElement
|
|
{
|
|
public string Text { get; set; } = string.Empty;
|
|
public Vector4 TextColor { get; set; } = new(1f, 1f, 1f, 1f);
|
|
|
|
public UiLabel() { ClickThrough = true; }
|
|
|
|
protected override void OnDraw(UiRenderContext ctx)
|
|
=> ctx.DrawString(Text, 0, 0, TextColor);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Simple clickable button: panel background + centered label + click
|
|
/// callback. Retail equivalent is Keystone's button widget, driven by
|
|
/// a <c>StateDesc</c> per <c>UIStateId</c> (normal / hot / pressed /
|
|
/// disabled) from the panel layout.
|
|
/// Note: the dat-widget button (Type 1 / UIElement_Button) is <see cref="AcDream.App.UI.UiButton"/>
|
|
/// in <c>UiButton.cs</c> — that is the production widget used by D.2b panels.
|
|
/// This class is the earlier dev-scaffold button (plain rect + text; no dat sprites).
|
|
/// </summary>
|
|
public class UiSimpleButton : UiPanel
|
|
{
|
|
public string Text { get; set; } = string.Empty;
|
|
public Vector4 TextColor { get; set; } = new(1f, 1f, 1f, 1f);
|
|
public event System.Action? Click;
|
|
|
|
public UiSimpleButton()
|
|
{
|
|
BackgroundColor = new Vector4(0.1f, 0.1f, 0.15f, 0.8f);
|
|
BorderColor = new Vector4(0.45f, 0.45f, 0.55f, 1f);
|
|
}
|
|
|
|
public override bool OnEvent(in UiEvent e)
|
|
{
|
|
if (e.Type == UiEventType.Click && Enabled)
|
|
{
|
|
Click?.Invoke();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected override void OnDraw(UiRenderContext ctx)
|
|
{
|
|
base.OnDraw(ctx);
|
|
if (Text.Length == 0 || ctx.DefaultFont is null) return;
|
|
|
|
float textW = ctx.DefaultFont.MeasureWidth(Text);
|
|
float tx = (Width - textW) * 0.5f;
|
|
float ty = (Height - ctx.DefaultFont.LineHeight) * 0.5f;
|
|
ctx.DrawString(Text, tx, ty, TextColor);
|
|
}
|
|
}
|