Browse Source

Properly raise surroundingText changed

pull/8963/head
Benedikt Stebner 3 years ago
parent
commit
8084bdbd78
  1. 6
      src/Android/Avalonia.Android/AndroidInputMethod.cs
  2. 80
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  3. 45
      src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

6
src/Android/Avalonia.Android/AndroidInputMethod.cs

@ -17,6 +17,8 @@ namespace Avalonia.Android
public ITextInputMethodClient Client { get; }
public bool IsActive { get; }
public InputMethodManager IMM { get; }
}
enum CustomImeFlags
@ -55,6 +57,8 @@ namespace Avalonia.Android
public ITextInputMethodClient Client => _client;
public InputMethodManager IMM => _imm;
public void Reset()
{
_imm.RestartInput(_host);
@ -96,7 +100,7 @@ namespace Avalonia.Android
{
var surroundingText = Client.SurroundingText;
_imm.UpdateSelection(_host, surroundingText.AnchorOffset, surroundingText.CursorOffset, surroundingText.AnchorOffset, surroundingText.CursorOffset);
_imm.UpdateSelection(_host, surroundingText.AnchorOffset, surroundingText.CursorOffset, _inputConnection.ComposingRegion.Start, _inputConnection.ComposingRegion.End);
}
}

80
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -262,9 +262,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
private readonly IAndroidInputMethod _inputMethod;
public InputConnectionImpl(View? targetView, IAndroidInputMethod inputMethod) :
public InputConnectionImpl(View targetView, IAndroidInputMethod inputMethod) :
base(targetView, false)
{
View = targetView;
_inputMethod = inputMethod;
}
@ -272,20 +274,12 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
}
public View View { get; }
public ComposingRegion ComposingRegion { get; private set; }
public string CompositionText { get; private set; }
public override bool SetSelection(int start, int end)
{
if (_inputMethod.IsActive)
{
_inputMethod.Client.SelectInSurroundingText(start, end);
}
return base.SetSelection(start, end);
}
public override bool SetComposingRegion(int start, int end)
{
if (_inputMethod.IsActive)
@ -300,21 +294,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform
return base.SetComposingRegion(start, end);
}
public override bool CommitCorrection(CorrectionInfo correctionInfo)
{
return base.CommitCorrection(correctionInfo);
}
public override bool DeleteSurroundingText(int beforeLength, int afterLength)
{
if (_inputMethod.IsActive && _inputMethod.Client.SupportsSurroundingText)
{
_inputMethod.Client.DeleteSurroundingText(beforeLength, afterLength);
}
return base.DeleteSurroundingText(beforeLength, afterLength);
}
public override ICharSequence GetTextBeforeCursorFormatted(int length, [GeneratedEnum] GetTextFlags flags)
{
if (_inputMethod.IsActive)
@ -329,7 +308,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
var text = surroundingText.Text.Substring(start, end - start);
//System.Diagnostics.Debug.WriteLine($"Text Before: {text}");
System.Diagnostics.Debug.WriteLine($"Text Before: {text}");
return new Java.Lang.String(text);
}
@ -352,7 +331,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
var text = surroundingText.Text.Substring(start, end - start);
//System.Diagnostics.Debug.WriteLine($"Text After: {text}");
System.Diagnostics.Debug.WriteLine($"Text After: {text}");
return new Java.Lang.String(text);
}
@ -368,16 +347,16 @@ namespace Avalonia.Android.Platform.SkiaPlatform
if (_inputMethod.IsActive)
{
_inputMethod.Client.SetPreeditText(CompositionText);
if (!string.IsNullOrEmpty(CompositionText))
{
ComposingRegion = default;
}
}
return base.SetComposingText(text, newCursorPosition);
}
public override bool SendKeyEvent(KeyEvent e)
{
return base.SendKeyEvent(e);
}
public override bool CommitText(ICharSequence text, int newCursorPosition)
{
CompositionText = null;
@ -386,32 +365,19 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
_inputMethod.Client.SetPreeditText(null);
if (string.IsNullOrEmpty(CompositionText) && ComposingRegion.Start != ComposingRegion.End)
var textLength = text.Length();
if (string.IsNullOrEmpty(CompositionText) && ComposingRegion.End > 0)
{
_inputMethod.Client.SelectInSurroundingText(ComposingRegion.Start, ComposingRegion.End);
_inputMethod.Client.SelectInSurroundingText(ComposingRegion.Start, ComposingRegion.Start + textLength);
}
ComposingRegion = new ComposingRegion(ComposingRegion.Start, ComposingRegion.Start + text.Length());
ComposingRegion = new ComposingRegion(ComposingRegion.Start, ComposingRegion.Start + textLength);
}
return base.CommitText(text, newCursorPosition);
}
public override bool PerformEditorAction([GeneratedEnum] ImeAction actionCode)
{
return base.PerformEditorAction(actionCode);
}
public override bool PerformPrivateCommand(string action, Bundle data)
{
return base.PerformPrivateCommand(action, data);
}
public override bool SendKeyEvent(KeyEvent e)
{
return base.SendKeyEvent(e);
}
public override bool FinishComposingText()
{
CompositionText = null;
@ -427,14 +393,16 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public readonly struct ComposingRegion
{
private readonly int _start = -1;
private readonly int _end = -1;
public ComposingRegion(int start, int end)
{
Start = start;
End = end;
_start = start;
_end = end;
}
public int Start { get; }
public int End { get; }
public int Start => _start;
public int End => _end;
}
}

45
src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

@ -43,7 +43,7 @@ namespace Avalonia.Controls
{
get
{
if(_presenter is null)
if(_presenter is null || _parent is null)
{
return default;
}
@ -56,7 +56,7 @@ namespace Avalonia.Controls
var lineText = _presenter.Text?.Substring(lineStart, textLine.Length);
var anchorOffset = Math.Max(0, _presenter.SelectionStart - lineStart);
var anchorOffset = Math.Max(0, _parent.SelectionStart - lineStart);
var cursorOffset = Math.Max(0, _presenter.SelectionEnd - lineStart);
@ -87,16 +87,19 @@ namespace Avalonia.Controls
public void SelectInSurroundingText(int start, int end)
{
if(_parent == null)
if(_parent is null ||_presenter is null)
{
return;
}
//start and end are relative to surroundingText
var surroundingText = SurroundingText;
var lineIndex = _presenter.TextLayout.GetLineIndexFromCharacterIndex(_presenter.CaretIndex, false);
var selectionStart = surroundingText.AnchorOffset + start;
var selectionEnd = surroundingText.AnchorOffset + end;
var textLine = _presenter.TextLayout.TextLines[lineIndex];
var lineStart = textLine.FirstTextSourceIndex;
var selectionStart = lineStart + start;
var selectionEnd = lineStart + end;
_parent.SelectionStart = selectionStart;
_parent.SelectionEnd = selectionEnd;
@ -104,13 +107,23 @@ namespace Avalonia.Controls
public void SetPresenter(TextPresenter? presenter, TextBox? parent)
{
if(_parent != null)
{
_parent.PropertyChanged -= OnParentPropertyChanged;
}
_parent = parent;
if(_parent != null)
{
_parent.PropertyChanged += OnParentPropertyChanged;
}
if (_presenter != null)
{
_presenter.PreeditText = null;
_presenter.CaretBoundsChanged -= OnCaretBoundsChanged;
_presenter.CaretBoundsChanged -= OnCaretBoundsChanged;
}
_presenter = presenter;
@ -125,6 +138,17 @@ namespace Avalonia.Controls
OnCaretBoundsChanged(this, EventArgs.Empty);
}
private void OnParentPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if(e.Property == TextBox.SelectionStartProperty || e.Property == TextBox.SelectionEndProperty)
{
if (SupportsSurroundingText)
{
SurroundingTextChanged?.Invoke(this, e);
}
}
}
public void DeleteSurroundingText(int beforeLength, int afterLength)
{
if (_parent != null && _presenter != null && string.IsNullOrEmpty(_presenter.PreeditText))
@ -142,11 +166,6 @@ namespace Avalonia.Controls
{
Dispatcher.UIThread.Post(() =>
{
if (SupportsSurroundingText)
{
SurroundingTextChanged?.Invoke(this, e);
}
CursorRectangleChanged?.Invoke(this, e);
}, DispatcherPriority.Input);

Loading…
Cancel
Save