| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- using System;
- using Android.Text;
- using Android.Views;
- using Android.Views.InputMethods;
- using Avalonia.Android.Platform.SkiaPlatform;
- using Avalonia.Input.TextInput;
- namespace Avalonia.Android.Platform.Input
- {
- internal class TextEditBuffer
- {
- private readonly IAndroidInputMethod _textInputMethod;
- private readonly TopLevelImpl _topLevel;
- private TextSelection? _composition;
- public TextEditBuffer(IAndroidInputMethod textInputMethod, TopLevelImpl topLevel)
- {
- _textInputMethod = textInputMethod;
- _topLevel = topLevel;
- }
- public bool HasComposition => Composition is { } composition && composition.Start != composition.End;
- public TextSelection Selection
- {
- get
- {
- var selection = _textInputMethod.Client?.Selection ?? default;
- return new TextSelection(Math.Min(selection.Start, selection.End), Math.Max(selection.Start, selection.End));
- }
- set
- {
- if (_textInputMethod.Client is { } client)
- client.Selection = value;
- }
- }
- public TextSelection? Composition
- {
- get => _composition; set
- {
- if (value is { } v)
- {
- var text = Text;
- var start = Math.Clamp(v.Start, 0, text.Length);
- var end = Math.Clamp(v.End, 0, text.Length);
- _composition = new TextSelection(Math.Min(start, end), Math.Max(start, end));
- }
- else
- _composition = null;
- }
- }
- public string? SelectedText
- {
- get
- {
- if(_textInputMethod.Client is not { } client || Selection.Start < 0 || Selection.End >= client.SurroundingText.Length)
- {
- return "";
- }
- var selection = Selection;
- return client.SurroundingText.Substring(selection.Start, selection.End - selection.Start);
- }
- }
- public string? ComposingText
- {
- get => !HasComposition ? null : Text?.Substring(Composition!.Value.Start, Composition!.Value.End - Composition!.Value.Start); set
- {
- if (HasComposition)
- {
- var start = Composition!.Value.Start;
- Replace(Composition!.Value.Start, Composition!.Value.End, value ?? "");
- Composition = new TextSelection(start, start + (value?.Length ?? 0));
- }
- else
- {
- var selection = Selection;
- Replace(selection.Start, selection.End, value ?? "");
- Composition = new TextSelection(selection.Start, selection.Start + (value?.Length ?? 0));
- }
- }
- }
- public string Text => _textInputMethod.Client?.SurroundingText ?? "";
- public ExtractedText? ExtractedText => new ExtractedText
- {
- Flags = Text.Contains('\n') ? 0 : ExtractedTextFlags.SingleLine,
- PartialStartOffset = -1,
- PartialEndOffset = Text.Length,
- SelectionStart = Selection.Start,
- SelectionEnd = Selection.End,
- StartOffset = 0,
- Text = new Java.Lang.String(Text)
- };
- internal void Remove(int index, int length)
- {
- if (_textInputMethod.Client is { } client)
- {
- client.Selection = new TextSelection(index, index + length);
- if (length > 0)
- _textInputMethod?.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
- }
- }
- internal void Replace(int start, int end, string text)
- {
- if (_textInputMethod.Client is { } client)
- {
- var realStart = Math.Min(start, end);
- var realEnd = Math.Max(start, end);
- if (realEnd > realStart)
- {
- client.Selection = new TextSelection(realStart, realEnd);
- _textInputMethod?.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
- }
- _topLevel.TextInput(text);
- var index = realStart + text.Length;
- client.Selection = new TextSelection(index, index);
- Composition = null;
- }
- }
- }
- }
|