|
|
@@ -3,7 +3,9 @@ using System.Collections.Generic;
|
|
|
using Android.App;
|
|
|
using Android.Content;
|
|
|
using Android.Graphics;
|
|
|
+using Android.OS;
|
|
|
using Android.Runtime;
|
|
|
+using Android.Text;
|
|
|
using Android.Views;
|
|
|
using Android.Views.InputMethods;
|
|
|
using Avalonia.Android.OpenGL;
|
|
|
@@ -23,6 +25,7 @@ using Avalonia.Platform.Storage;
|
|
|
using Avalonia.Rendering;
|
|
|
using Avalonia.Rendering.Composition;
|
|
|
using Java.Lang;
|
|
|
+using Math = System.Math;
|
|
|
|
|
|
namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
{
|
|
|
@@ -276,8 +279,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
{
|
|
|
throw new NotImplementedException();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
internal class AvaloniaInputConnection : BaseInputConnection
|
|
|
@@ -293,11 +294,12 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public TextInputMethodSurroundingText SurroundingText { get; set; }
|
|
|
|
|
|
- public string ComposingText { get; private set; }
|
|
|
+ public string ComposingText { get; internal set; }
|
|
|
|
|
|
- public ComposingRegion ComposingRegion { get; private set; }
|
|
|
+ public ComposingRegion? ComposingRegion { get; internal set; }
|
|
|
|
|
|
- public bool IsComposing { get; private set; }
|
|
|
+ public bool IsComposing => !string.IsNullOrEmpty(ComposingText);
|
|
|
+ public bool IsCommiting { get; private set; }
|
|
|
|
|
|
public override bool SetComposingRegion(int start, int end)
|
|
|
{
|
|
|
@@ -314,8 +316,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
ComposingText = composingText;
|
|
|
|
|
|
- IsComposing = true;
|
|
|
-
|
|
|
_inputMethod.Client?.SetPreeditText(ComposingText);
|
|
|
|
|
|
return base.SetComposingText(text, newCursorPosition);
|
|
|
@@ -323,20 +323,25 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public override bool FinishComposingText()
|
|
|
{
|
|
|
- IsComposing = false;
|
|
|
-
|
|
|
- ComposingRegion = new ComposingRegion(SurroundingText.CursorOffset, SurroundingText.CursorOffset);
|
|
|
+ if (!string.IsNullOrEmpty(ComposingText))
|
|
|
+ {
|
|
|
+ CommitText(ComposingText, ComposingText.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ComposingRegion = new ComposingRegion(SurroundingText.CursorOffset, SurroundingText.CursorOffset);
|
|
|
+ }
|
|
|
|
|
|
return base.FinishComposingText();
|
|
|
}
|
|
|
|
|
|
public override ICharSequence GetTextBeforeCursorFormatted(int length, [GeneratedEnum] GetTextFlags flags)
|
|
|
{
|
|
|
- if (!string.IsNullOrEmpty(SurroundingText.Text))
|
|
|
+ if (!string.IsNullOrEmpty(SurroundingText.Text) && length > 0)
|
|
|
{
|
|
|
var start = System.Math.Max(SurroundingText.CursorOffset - length, 0);
|
|
|
|
|
|
- var end = System.Math.Min(start + length, SurroundingText.CursorOffset);
|
|
|
+ var end = System.Math.Min(start + length - 1, SurroundingText.CursorOffset);
|
|
|
|
|
|
var text = SurroundingText.Text.Substring(start, end - start);
|
|
|
|
|
|
@@ -368,11 +373,31 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public override bool CommitText(ICharSequence text, int newCursorPosition)
|
|
|
{
|
|
|
+ IsCommiting = true;
|
|
|
var committedText = text.ToString();
|
|
|
|
|
|
_inputMethod.Client.SetPreeditText(null);
|
|
|
|
|
|
- _inputMethod.Client.SelectInSurroundingText(ComposingRegion.Start, ComposingRegion.End);
|
|
|
+ int? start, end;
|
|
|
+
|
|
|
+ if(SurroundingText.CursorOffset != SurroundingText.AnchorOffset)
|
|
|
+ {
|
|
|
+ start = Math.Min(SurroundingText.CursorOffset, SurroundingText.AnchorOffset);
|
|
|
+ end = Math.Max(SurroundingText.CursorOffset, SurroundingText.AnchorOffset);
|
|
|
+ }
|
|
|
+ else if (ComposingRegion != null)
|
|
|
+ {
|
|
|
+ start = ComposingRegion?.Start;
|
|
|
+ end = ComposingRegion?.End;
|
|
|
+
|
|
|
+ ComposingRegion = null;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ start = end = _inputMethod.Client.SurroundingText.CursorOffset;
|
|
|
+ }
|
|
|
+
|
|
|
+ _inputMethod.Client.SelectInSurroundingText((int)start, (int)end);
|
|
|
|
|
|
var time = DateTime.Now.TimeOfDay;
|
|
|
|
|
|
@@ -380,15 +405,29 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
_topLevel.Input(rawTextEvent);
|
|
|
|
|
|
+ ComposingText = null;
|
|
|
+
|
|
|
+ ComposingRegion = new ComposingRegion(newCursorPosition, newCursorPosition);
|
|
|
+
|
|
|
return base.CommitText(text, newCursorPosition);
|
|
|
}
|
|
|
|
|
|
public override bool DeleteSurroundingText(int beforeLength, int afterLength)
|
|
|
{
|
|
|
- _inputMethod.Client.SelectInSurroundingText(beforeLength, afterLength);
|
|
|
+ var surroundingText = _inputMethod.Client.SurroundingText;
|
|
|
+
|
|
|
+ var selectionStart = surroundingText.CursorOffset;
|
|
|
+
|
|
|
+ _inputMethod.Client.SelectInSurroundingText(selectionStart - beforeLength, selectionStart + afterLength);
|
|
|
|
|
|
_inputMethod.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
|
|
|
|
|
|
+ surroundingText = _inputMethod.Client.SurroundingText;
|
|
|
+
|
|
|
+ selectionStart = surroundingText.CursorOffset;
|
|
|
+
|
|
|
+ ComposingRegion = new ComposingRegion(selectionStart, selectionStart);
|
|
|
+
|
|
|
return base.DeleteSurroundingText(beforeLength, afterLength);
|
|
|
}
|
|
|
|
|
|
@@ -396,22 +435,23 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
{
|
|
|
_inputMethod.Client.SelectInSurroundingText(start, end);
|
|
|
|
|
|
+ ComposingRegion = new ComposingRegion(start, end);
|
|
|
+
|
|
|
return base.SetSelection(start, end);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- public readonly struct ComposingRegion
|
|
|
- {
|
|
|
- private readonly int _start = -1;
|
|
|
- private readonly int _end = -1;
|
|
|
|
|
|
- public ComposingRegion(int start, int end)
|
|
|
+ public override bool PerformEditorAction([GeneratedEnum] ImeAction actionCode)
|
|
|
{
|
|
|
- _start = start;
|
|
|
- _end = end;
|
|
|
- }
|
|
|
+ switch (actionCode)
|
|
|
+ {
|
|
|
+ case ImeAction.Done:
|
|
|
+ {
|
|
|
+ _inputMethod.IMM.HideSoftInputFromWindow(_inputMethod.View.WindowToken, HideSoftInputFlags.ImplicitOnly);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- public int Start => _start;
|
|
|
- public int End => _end;
|
|
|
+ return base.PerformEditorAction(actionCode);
|
|
|
+ }
|
|
|
}
|
|
|
}
|