Implement INPUTNAME string opcodes
This commit is contained in:
87
godot/FullwidthTextEditorDialog.cs
Normal file
87
godot/FullwidthTextEditorDialog.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using Age.Engine.Sys4;
|
||||
using Godot;
|
||||
|
||||
/// <summary>Godot presentation for AGERc command 10's blocking INPUTNAME editor.</summary>
|
||||
public partial class FullwidthTextEditorDialog : Window
|
||||
{
|
||||
private readonly LineEdit _edit = new() { MaxLength = 255 };
|
||||
private readonly Label _error = new()
|
||||
{
|
||||
AutowrapMode = TextServer.AutowrapMode.WordSmart,
|
||||
CustomMinimumSize = new Vector2(0, 28),
|
||||
};
|
||||
private bool _completed;
|
||||
|
||||
public event Action<bool, string>? EditCompleted;
|
||||
|
||||
public FullwidthTextEditorDialog()
|
||||
{
|
||||
Title = "文字入力";
|
||||
Exclusive = true;
|
||||
Transient = true;
|
||||
Unresizable = true;
|
||||
|
||||
var margin = new MarginContainer();
|
||||
margin.AddThemeConstantOverride("margin_left", 16);
|
||||
margin.AddThemeConstantOverride("margin_top", 16);
|
||||
margin.AddThemeConstantOverride("margin_right", 16);
|
||||
margin.AddThemeConstantOverride("margin_bottom", 16);
|
||||
AddChild(margin);
|
||||
margin.SetAnchorsAndOffsetsPreset(Control.LayoutPreset.FullRect);
|
||||
|
||||
var column = new VBoxContainer();
|
||||
margin.AddChild(column);
|
||||
column.AddChild(new Label { Text = "全角文字で名前を入力してください。" });
|
||||
_edit.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
|
||||
column.AddChild(_edit);
|
||||
_error.AddThemeColorOverride("font_color", new Color(1.0f, 0.35f, 0.35f));
|
||||
column.AddChild(_error);
|
||||
|
||||
var actions = new HBoxContainer { Alignment = BoxContainer.AlignmentMode.End };
|
||||
var cancel = new Button { Text = "キャンセル" };
|
||||
var accept = new Button { Text = "決定" };
|
||||
actions.AddChild(cancel);
|
||||
actions.AddChild(accept);
|
||||
column.AddChild(actions);
|
||||
|
||||
accept.Pressed += TryAccept;
|
||||
cancel.Pressed += Cancel;
|
||||
_edit.TextSubmitted += _ => TryAccept();
|
||||
CloseRequested += Cancel;
|
||||
}
|
||||
|
||||
public void Open(string initialText)
|
||||
{
|
||||
_completed = false;
|
||||
_error.Text = "";
|
||||
_edit.Text = initialText;
|
||||
PopupCentered(new Vector2I(430, 160));
|
||||
_edit.GrabFocus();
|
||||
_edit.SelectAll();
|
||||
}
|
||||
|
||||
private void TryAccept()
|
||||
{
|
||||
FullwidthTextValidationError error = Cp932Text.ValidateFullwidthName(_edit.Text);
|
||||
if (error != FullwidthTextValidationError.None)
|
||||
{
|
||||
_error.Text = error == FullwidthTextValidationError.TooLong
|
||||
? "字数オーバーです"
|
||||
: "半角文字は使用できません";
|
||||
_edit.GrabFocus();
|
||||
return;
|
||||
}
|
||||
Complete(true);
|
||||
}
|
||||
|
||||
private void Cancel() => Complete(false);
|
||||
|
||||
private void Complete(bool accepted)
|
||||
{
|
||||
if (_completed) return;
|
||||
_completed = true;
|
||||
Hide();
|
||||
EditCompleted?.Invoke(accepted, _edit.Text);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ public sealed class GodotAdvHost : IHost
|
||||
private readonly ScriptPresentationBarrier _presentationBarrier = new();
|
||||
private readonly AutoResetEvent _presentationRequestConsumed = new(false);
|
||||
private readonly AutoResetEvent _diagnosticMessageCompleted = new(false);
|
||||
private readonly AutoResetEvent _fullwidthTextEditCompleted = new(false);
|
||||
private readonly object _fullwidthTextEditLock = new();
|
||||
private FullwidthTextEditResult _fullwidthTextEditResult;
|
||||
private readonly bool _synchronizeExplicitPresentation;
|
||||
private long _explicitPresentationRequestGeneration;
|
||||
private long _consumedPresentationRequestGeneration;
|
||||
@@ -132,6 +135,28 @@ public sealed class GodotAdvHost : IHost
|
||||
|
||||
public void CompleteDiagnosticMessage() => _diagnosticMessageCompleted.Set();
|
||||
|
||||
public FullwidthTextEditResult EditFullwidthString(FullwidthTextEditRequest request)
|
||||
{
|
||||
if (_stopping) return new(false, request.CurrentText);
|
||||
lock (_fullwidthTextEditLock)
|
||||
_fullwidthTextEditResult = new(false, request.CurrentText);
|
||||
_timeline?.Event("fullwidth-text-edit", new()
|
||||
{
|
||||
["current"] = request.CurrentText,
|
||||
["initial"] = request.InitialText,
|
||||
});
|
||||
_main.CallDeferred("ShowAgeFullwidthTextEditor", request.InitialText);
|
||||
while (!_stopping && !_fullwidthTextEditCompleted.WaitOne(50)) { }
|
||||
lock (_fullwidthTextEditLock) return _fullwidthTextEditResult;
|
||||
}
|
||||
|
||||
public void CompleteFullwidthTextEdit(bool accepted, string text)
|
||||
{
|
||||
lock (_fullwidthTextEditLock)
|
||||
_fullwidthTextEditResult = new(accepted, text);
|
||||
_fullwidthTextEditCompleted.Set();
|
||||
}
|
||||
|
||||
private string CurrentScene
|
||||
{
|
||||
get { lock (_scriptContextLock) return _scriptContexts.TryPeek(out var scene) ? scene : _rootScene; }
|
||||
@@ -966,6 +991,7 @@ public sealed class GodotAdvHost : IHost
|
||||
_inputCallbackSignal.Set();
|
||||
_frameSignal.Set();
|
||||
_diagnosticMessageCompleted.Set();
|
||||
_fullwidthTextEditCompleted.Set();
|
||||
}
|
||||
|
||||
public void ResetSceneContext()
|
||||
|
||||
@@ -69,6 +69,7 @@ public partial class Main : Godot.Control
|
||||
private Sys4RegIniStore? _sys4RegIniStore;
|
||||
private VirtualMachine _vm = null!;
|
||||
private GodotAdvHost _host = null!;
|
||||
private FullwidthTextEditorDialog? _fullwidthTextEditor;
|
||||
private Sys4ScriptProvider? _scripts;
|
||||
private DebugSceneLauncher? _debugSceneLauncher;
|
||||
private IReadOnlyList<DebugSceneEntry> _debugSceneEntries = System.Array.Empty<DebugSceneEntry>();
|
||||
@@ -928,6 +929,26 @@ public partial class Main : Godot.Control
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowAgeFullwidthTextEditor(string initialText)
|
||||
{
|
||||
if (_fullwidthTextEditor != null)
|
||||
{
|
||||
GD.PushWarning("[inputname] replaced an already-open full-width text editor");
|
||||
_fullwidthTextEditor.QueueFree();
|
||||
}
|
||||
|
||||
var editor = new FullwidthTextEditorDialog();
|
||||
_fullwidthTextEditor = editor;
|
||||
editor.EditCompleted += (accepted, text) =>
|
||||
{
|
||||
if (_fullwidthTextEditor == editor) _fullwidthTextEditor = null;
|
||||
_host?.CompleteFullwidthTextEdit(accepted, text);
|
||||
editor.QueueFree();
|
||||
};
|
||||
AddChild(editor);
|
||||
editor.Open(initialText);
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
bool vmStopped = true;
|
||||
|
||||
Reference in New Issue
Block a user