csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.9 KiB
145 lines
3.9 KiB
using System;
|
|
using Avalonia.Input.TextInput;
|
|
using Avalonia.Media.TextFormatting;
|
|
using Avalonia.Native.Interop;
|
|
|
|
#nullable enable
|
|
|
|
namespace Avalonia.Native
|
|
{
|
|
internal class AvaloniaNativeTextInputMethod : ITextInputMethodImpl, IDisposable
|
|
{
|
|
private TextInputMethodClient? _client;
|
|
private IAvnTextInputMethodClient? _nativeClient;
|
|
private readonly IAvnTextInputMethod _inputMethod;
|
|
|
|
public AvaloniaNativeTextInputMethod(IAvnWindowBase nativeWindow)
|
|
{
|
|
_inputMethod = nativeWindow.InputMethod;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_inputMethod.Dispose();
|
|
_nativeClient?.Dispose();
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_inputMethod.Reset();
|
|
}
|
|
|
|
public void SetClient(TextInputMethodClient? client)
|
|
{
|
|
if (_client is { SupportsSurroundingText: true })
|
|
{
|
|
_client.SurroundingTextChanged -= OnSurroundingTextChanged;
|
|
_client.CursorRectangleChanged -= OnCursorRectangleChanged;
|
|
|
|
_nativeClient?.Dispose();
|
|
}
|
|
|
|
_nativeClient = null;
|
|
_client = client;
|
|
|
|
if (_client != null)
|
|
{
|
|
_nativeClient = new AvnTextInputMethodClient(_client);
|
|
|
|
OnSurroundingTextChanged(this, EventArgs.Empty);
|
|
OnCursorRectangleChanged(this, EventArgs.Empty);
|
|
|
|
_client.SurroundingTextChanged += OnSurroundingTextChanged;
|
|
_client.CursorRectangleChanged += OnCursorRectangleChanged;
|
|
}
|
|
|
|
_inputMethod.SetClient(_nativeClient);
|
|
}
|
|
|
|
private void OnCursorRectangleChanged(object? sender, EventArgs e)
|
|
{
|
|
if (_client == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var textViewVisual = _client.TextViewVisual;
|
|
|
|
if(textViewVisual is null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var visualRoot = textViewVisual.VisualRoot;
|
|
|
|
if(visualRoot is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var transform = textViewVisual.TransformToVisual((Visual)visualRoot);
|
|
|
|
if (transform == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var rect = _client.CursorRectangle.TransformToAABB(transform.Value);
|
|
|
|
_inputMethod.SetCursorRect(rect.ToAvnRect());
|
|
}
|
|
|
|
private void OnSurroundingTextChanged(object? sender, EventArgs e)
|
|
{
|
|
if (_client == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var surroundingText = _client.SurroundingText;
|
|
var selection = _client.Selection;
|
|
|
|
_inputMethod.SetSurroundingText(
|
|
surroundingText ?? "",
|
|
selection.Start,
|
|
selection.End
|
|
);
|
|
}
|
|
|
|
public void SetCursorRect(Rect rect)
|
|
{
|
|
_inputMethod.SetCursorRect(rect.ToAvnRect());
|
|
}
|
|
|
|
public void SetOptions(TextInputOptions options)
|
|
{
|
|
|
|
}
|
|
|
|
private class AvnTextInputMethodClient : NativeCallbackBase, IAvnTextInputMethodClient
|
|
{
|
|
private readonly TextInputMethodClient _client;
|
|
|
|
public AvnTextInputMethodClient(TextInputMethodClient client)
|
|
{
|
|
_client = client;
|
|
}
|
|
|
|
public void SetPreeditText(string preeditText)
|
|
{
|
|
if (_client.SupportsPreedit)
|
|
{
|
|
_client.SetPreeditText(preeditText);
|
|
}
|
|
}
|
|
|
|
public void SelectInSurroundingText(int start, int end)
|
|
{
|
|
if (_client.SupportsSurroundingText)
|
|
{
|
|
_client.Selection = new TextSelection(start, end);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|