feat(D.2b): UiChatInput — editable field, caret, 100-entry history (UIElement_Text port)
Ports retail UIElement_Text editable one-line mode (caret = glyph index;
caret pixel-X = sum of glyph advances via UiDatFont) and ChatInterface's
100-entry command history (up/down arrow; sentinel -1 = live line).
Submit (Enter/KeypadEnter) fires OnSubmit callback, clears, pushes history.
Draws via DrawStringDat (dat font) or DrawString (BitmapFont) fallback.
AcceptsFocus=true + IsEditControl=true so UiRoot routes Char/KeyDown to it
and suppresses global hotkeys while typing. 6 new tests, all green.
Decomp refs: UIElement_Text::MoveCursor @0x468d00,
UIElement_Text::FindPixelsFromPos @0x472b40,
ChatInterface::ProcessCommand @0x4f5100
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2940b4e3b2
commit
bcc45d668e
2 changed files with 230 additions and 0 deletions
72
tests/AcDream.App.Tests/UI/UiChatInputTests.cs
Normal file
72
tests/AcDream.App.Tests/UI/UiChatInputTests.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using AcDream.App.UI;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.App.Tests.UI;
|
||||
|
||||
public class UiChatInputTests
|
||||
{
|
||||
[Fact]
|
||||
public void InsertChar_AdvancesCaret()
|
||||
{
|
||||
var input = new UiChatInput();
|
||||
input.InsertChar('h'); input.InsertChar('i');
|
||||
Assert.Equal("hi", input.Text);
|
||||
Assert.Equal(2, input.CaretPos);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Backspace_DeletesBeforeCaret()
|
||||
{
|
||||
var input = new UiChatInput();
|
||||
foreach (var c in "abc") input.InsertChar(c);
|
||||
input.MoveCaret(-1);
|
||||
input.Backspace();
|
||||
Assert.Equal("ac", input.Text);
|
||||
Assert.Equal(1, input.CaretPos);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Submit_FiresCallback_ClearsText_PushesHistory()
|
||||
{
|
||||
string? sent = null;
|
||||
var input = new UiChatInput { OnSubmit = t => sent = t };
|
||||
foreach (var c in "hello") input.InsertChar(c);
|
||||
input.Submit();
|
||||
Assert.Equal("hello", sent);
|
||||
Assert.Equal("", input.Text);
|
||||
Assert.Equal(0, input.CaretPos);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptySubmit_DoesNotFire()
|
||||
{
|
||||
int n = 0;
|
||||
var input = new UiChatInput { OnSubmit = _ => n++ };
|
||||
input.Submit();
|
||||
Assert.Equal(0, n);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void History_UpDownBrowsesPreviousSubmissions()
|
||||
{
|
||||
var input = new UiChatInput { OnSubmit = _ => {} };
|
||||
foreach (var c in "first") input.InsertChar(c); input.Submit();
|
||||
foreach (var c in "second") input.InsertChar(c); input.Submit();
|
||||
input.HistoryPrev();
|
||||
Assert.Equal("second", input.Text);
|
||||
input.HistoryPrev();
|
||||
Assert.Equal("first", input.Text);
|
||||
input.HistoryNext();
|
||||
Assert.Equal("second", input.Text);
|
||||
input.HistoryNext();
|
||||
Assert.Equal("", input.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void History_CapsAt100()
|
||||
{
|
||||
var input = new UiChatInput { OnSubmit = _ => {} };
|
||||
for (int i = 0; i < 150; i++) { input.InsertChar('x'); input.Submit(); }
|
||||
Assert.True(input.HistoryCount <= 100);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue