mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-05-11 19:07:42 +02:00
153 lines
5.3 KiB
C#
153 lines
5.3 KiB
C#
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Threading;
|
|
using Ryujinx.Ava.Input;
|
|
using Ryujinx.Ava.UI.Helpers;
|
|
using Ryujinx.Ava.UI.Windows;
|
|
using Ryujinx.HLE.UI;
|
|
using System;
|
|
using System.Threading;
|
|
using HidKey = Ryujinx.Common.Configuration.Hid.Key;
|
|
|
|
namespace Ryujinx.Ava.UI.Applet
|
|
{
|
|
class AvaloniaDynamicTextInputHandler : IDynamicTextInputHandler
|
|
{
|
|
private MainWindow _parent;
|
|
private readonly OffscreenTextBox _hiddenTextBox;
|
|
private bool _canProcessInput;
|
|
private IDisposable _textChangedSubscription;
|
|
private IDisposable _selectionStartChangedSubscription;
|
|
private IDisposable _selectionEndtextChangedSubscription;
|
|
|
|
public AvaloniaDynamicTextInputHandler(MainWindow parent)
|
|
{
|
|
_parent = parent;
|
|
|
|
if (_parent.InputManager.KeyboardDriver is AvaloniaKeyboardDriver avaloniaKeyboardDriver)
|
|
{
|
|
avaloniaKeyboardDriver.KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed;
|
|
avaloniaKeyboardDriver.KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease;
|
|
avaloniaKeyboardDriver.TextInput += AvaloniaDynamicTextInputHandler_TextInput;
|
|
}
|
|
|
|
_hiddenTextBox = _parent.HiddenTextBox;
|
|
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
_textChangedSubscription = _hiddenTextBox.GetObservable(TextBox.TextProperty).Subscribe(TextChanged);
|
|
_selectionStartChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionStartProperty).Subscribe(SelectionChanged);
|
|
_selectionEndtextChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionEndProperty).Subscribe(SelectionChanged);
|
|
});
|
|
}
|
|
|
|
private void TextChanged(string text)
|
|
{
|
|
TextChangedEvent?.Invoke(text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, false);
|
|
}
|
|
|
|
private void SelectionChanged(int _)
|
|
{
|
|
TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, false);
|
|
}
|
|
|
|
private void AvaloniaDynamicTextInputHandler_TextInput(object sender, string text)
|
|
{
|
|
Dispatcher.UIThread.InvokeAsync(() =>
|
|
{
|
|
if (_canProcessInput)
|
|
{
|
|
_hiddenTextBox.SendText(text);
|
|
}
|
|
});
|
|
}
|
|
|
|
private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, KeyEventArgs e)
|
|
{
|
|
HidKey key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
|
|
|
if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true))
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent();
|
|
|
|
Dispatcher.UIThread.InvokeAsync(() =>
|
|
{
|
|
if (_canProcessInput)
|
|
{
|
|
_hiddenTextBox.SendKeyUpEvent(e);
|
|
}
|
|
});
|
|
}
|
|
|
|
private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, KeyEventArgs e)
|
|
{
|
|
HidKey key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
|
|
|
if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true))
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent();
|
|
|
|
Dispatcher.UIThread.InvokeAsync(() =>
|
|
{
|
|
if (_canProcessInput)
|
|
{
|
|
_hiddenTextBox.SendKeyDownEvent(e);
|
|
}
|
|
});
|
|
}
|
|
|
|
public bool TextProcessingEnabled
|
|
{
|
|
get => Volatile.Read(ref _canProcessInput);
|
|
set => Volatile.Write(ref _canProcessInput, value);
|
|
}
|
|
|
|
public event DynamicTextChangedHandler TextChangedEvent;
|
|
public event KeyPressedHandler KeyPressedEvent;
|
|
public event KeyReleasedHandler KeyReleasedEvent;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_parent.InputManager.KeyboardDriver is AvaloniaKeyboardDriver avaloniaKeyboardDriver)
|
|
{
|
|
avaloniaKeyboardDriver.KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed;
|
|
avaloniaKeyboardDriver.KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease;
|
|
avaloniaKeyboardDriver.TextInput -= AvaloniaDynamicTextInputHandler_TextInput;
|
|
}
|
|
|
|
_textChangedSubscription?.Dispose();
|
|
_selectionStartChangedSubscription?.Dispose();
|
|
_selectionEndtextChangedSubscription?.Dispose();
|
|
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
_hiddenTextBox.Clear();
|
|
_parent.ViewModel.RendererHostControl.Focus();
|
|
|
|
_parent = null;
|
|
});
|
|
}
|
|
|
|
public void SetText(string text, int cursorBegin) =>
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
_hiddenTextBox.Text = text;
|
|
_hiddenTextBox.CaretIndex = cursorBegin;
|
|
});
|
|
|
|
public void SetText(string text, int cursorBegin, int cursorEnd) =>
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
_hiddenTextBox.Text = text;
|
|
_hiddenTextBox.SelectionStart = cursorBegin;
|
|
_hiddenTextBox.SelectionEnd = cursorEnd;
|
|
});
|
|
}
|
|
}
|