feat: add overlay manager
- compose visible overlays into rendered lines - add runtime APIs for showing and hiding overlays - restore focus when overlays close - add help overlay example
This commit is contained in:
+48
-2
@@ -1,6 +1,7 @@
|
||||
using TinyTUI;
|
||||
using TinyTUI.Components;
|
||||
using TinyTUI.Input;
|
||||
using TinyTUI.Overlay;
|
||||
using TinyTUI.Rendering;
|
||||
using TinyTUI.Runtime;
|
||||
using TinyTUI.Stdio;
|
||||
@@ -22,7 +23,16 @@ var input = new TinyTUI.Components.Input(textMeasurer) { Prompt = "请输入: "
|
||||
input.OnChanged = value => UpdateStatus(statusText, value, textMeasurer, renderer);
|
||||
input.OnSubmitted = value =>
|
||||
{
|
||||
AddEvent(eventsText, $"Submitted: {value}");
|
||||
if (value.Trim() == "/help")
|
||||
{
|
||||
AddEvent(eventsText, "Overlay: help opened");
|
||||
runtime.ShowOverlay(new HelpOverlay(runtime, textMeasurer));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEvent(eventsText, $"Submitted: {value}");
|
||||
}
|
||||
|
||||
input.Clear();
|
||||
};
|
||||
input.OnCanceled = () => done.Set();
|
||||
@@ -32,7 +42,7 @@ UpdateStatus(statusText, input.Value, textMeasurer, renderer);
|
||||
var page = new Container();
|
||||
page.Add(new Text("TinyTUI 基础组件示例"));
|
||||
page.Add(new Text("======================"));
|
||||
page.Add(new Text("测试方式: 输入文本 Backspace 删除 Enter 提交 Esc 退出"));
|
||||
page.Add(new Text("测试方式: 输入文本 Backspace 删除 Enter 提交 /help 打开弹层 Esc 退出"));
|
||||
page.Add(new Text(string.Empty));
|
||||
page.Add(new Box(statusText, textMeasurer) { Title = "状态" });
|
||||
page.Add(new Text(string.Empty));
|
||||
@@ -78,3 +88,39 @@ static void AddEvent(Text eventsText, string message)
|
||||
var lines = eventsText.Value.Split('\n').Skip(1).Append($"- {message}").TakeLast(8);
|
||||
eventsText.Value = "最近事件:\n" + string.Join('\n', lines);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于手动验证 overlay 的帮助弹层
|
||||
/// </summary>
|
||||
file sealed class HelpOverlay(ITuiRuntime runtime, ITextMeasurer textMeasurer) : IInputComponent
|
||||
{
|
||||
private readonly Box _box = new(
|
||||
new Text(
|
||||
"Overlay 示例\n" +
|
||||
"\n" +
|
||||
"这个弹层由 Runtime 显示\n" +
|
||||
"OverlayManager 会把它合成到基础页面上\n" +
|
||||
"显示时焦点会切到弹层\n" +
|
||||
"关闭后焦点会恢复到输入框\n" +
|
||||
"\n" +
|
||||
"按 Enter 或 Esc 关闭"),
|
||||
textMeasurer)
|
||||
{
|
||||
Title = "Help",
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<string> Render(int width)
|
||||
{
|
||||
return _box.Render(width);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void HandleInput(TuiInputEvent input)
|
||||
{
|
||||
if (input is { Kind: TuiInputEventKind.Key, Value: KeyNames.Enter or KeyNames.Escape })
|
||||
{
|
||||
runtime.HideOverlay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user