diff options
author | Emmanuel Hansen <emmausssss@gmail.com> | 2022-05-15 11:30:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-15 13:30:15 +0200 |
commit | deb99d2cae3e80bdf70cb52c6c160094dc7c9292 (patch) | |
tree | e60f44d1b4bd45bbf36fcfa750fb99787febfdbe /Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs | |
parent | 9ba73ffbe5f78c0403cf102b95768f388da05122 (diff) |
Avalonia UI - Part 1 (#3270)1.1.122
* avalonia part 1
* remove vulkan ui backend
* move ui common files to ui common project
* get name for oading screen from device
* rebase.
* review 1
* review 1.1
* review
* cleanup
* addressed review
* use cancellation token
* review
* review
* rebased
* cancel library loading when closing window
* remove star image, use fonticon instead
* delete render control frame buffer when game ends. change position of fav star
* addressed @Thog review
* ensure the right ui is downloaded in updates
* fix crash when showing not supported dialog during controller request
* add prefix to artifact names
* Auto-format Avalonia project
* Fix input
* Fix build, simplify app disposal
* remove nv stutter thread
* addressed review
* add missing change
* maintain window size if new size is zero length
* add game, handheld, docked to local
* reverse scale main window
* Update de_DE.json
* Update de_DE.json
* Update de_DE.json
* Update italian json
* Update it_IT.json
* let render timer poll with no wait
* remove unused code
* more unused code
* enabled tiered compilation and trimming
* check if window event is not closed before signaling
* fix atmospher case
* locale fix
* locale fix
* remove explicit tiered compilation declarations
* Remove ) it_IT.json
* Remove ) de_DE.json
* Update it_IT.json
* Update pt_BR locale with latest strings
* Remove ')'
* add more strings to locale
* update locale
* remove extra slash
* remove extra slash
* set firmware version to 0 if key's not found
* fix
* revert timer changes
* lock on object instead
* Update it_IT.json
* remove unused method
* add load screen text to locale
* drop swap event
* Update de_DE.json
* Update de_DE.json
* do null check when stopping emulator
* Update de_DE.json
* Create tr_TR.json
* Add tr_TR
* Add tr_TR + Turkish
* Update it_IT.json
* Update Ryujinx.Ava/Input/AvaloniaMappingHelper.cs
Co-authored-by: Ac_K <Acoustik666@gmail.com>
* Apply suggestions from code review
Co-authored-by: Ac_K <Acoustik666@gmail.com>
* Apply suggestions from code review
Co-authored-by: Ac_K <Acoustik666@gmail.com>
* addressed review
* Update Ryujinx.Ava/Ui/Backend/OpenGl/OpenGlRenderTarget.cs
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
* use avalonia's inbuilt renderer on linux
* removed whitespace
* workaround for queue render crash with vsync off
* drop custom backend
* format files
* fix not closing issue
* remove warnings
* rebase
* update avalonia library
* Reposition the Text and Button on About Page
* Assign build version
* Remove appveyor text
Co-authored-by: gdk <gab.dark.100@gmail.com>
Co-authored-by: Niwu34 <67392333+Niwu34@users.noreply.github.com>
Co-authored-by: Antonio Brugnolo <36473846+AntoSkate@users.noreply.github.com>
Co-authored-by: aegiff <99728970+aegiff@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
Co-authored-by: MostlyWhat <78652091+MostlyWhat@users.noreply.github.com>
Diffstat (limited to 'Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs')
-rw-r--r-- | Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs b/Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs new file mode 100644 index 00000000..714b6360 --- /dev/null +++ b/Ryujinx.Ava/Ui/Applet/AvaloniaDynamicTextInputHandler.cs @@ -0,0 +1,162 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Threading; +using OpenTK.Windowing.Common; +using Ryujinx.Ava.Input; +using Ryujinx.Ava.Ui.Controls; +using Ryujinx.Ava.Ui.Windows; +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.HLE.Ui; +using System; +using System.Threading; + +namespace Ryujinx.Ava.Ui.Applet +{ + class AvaloniaDynamicTextInputHandler : IDynamicTextInputHandler + { + private MainWindow _parent; + private OffscreenTextBox _hiddenTextBox; + private bool _canProcessInput; + private IDisposable _textChangedSubscription; + private IDisposable _selectionStartChangedSubscription; + private IDisposable _selectionEndtextChangedSubscription; + + public AvaloniaDynamicTextInputHandler(MainWindow parent) + { + _parent = parent; + + (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed; + (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease; + (_parent.InputManager.KeyboardDriver as 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, true); + } + + private void SelectionChanged(int selection) + { + if (_hiddenTextBox.SelectionEnd < _hiddenTextBox.SelectionStart) + { + _hiddenTextBox.SelectionStart = _hiddenTextBox.SelectionEnd; + } + + TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true); + } + + private void AvaloniaDynamicTextInputHandler_TextInput(object sender, TextInputEventArgs e) + { + Dispatcher.UIThread.InvokeAsync(() => + { + if (_canProcessInput) + { + _hiddenTextBox.SendText(e.AsString); + } + }); + } + + private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, Avalonia.Input.KeyEventArgs e) + { + var key = (Key)AvaloniaMappingHelper.ToInputKey(e.Key); + + if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true)) + { + return; + } + + e.RoutedEvent = _hiddenTextBox.GetKeyUpRoutedEvent(); + + Dispatcher.UIThread.InvokeAsync(() => + { + if (_canProcessInput) + { + _hiddenTextBox.SendKeyUpEvent(e); + } + }); + } + + private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, Avalonia.Input.KeyEventArgs e) + { + var key = (Key)AvaloniaMappingHelper.ToInputKey(e.Key); + + if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true)) + { + return; + } + + e.RoutedEvent = _hiddenTextBox.GetKeyUpRoutedEvent(); + + Dispatcher.UIThread.InvokeAsync(() => + { + if (_canProcessInput) + { + _hiddenTextBox.SendKeyDownEvent(e); + } + }); + } + + public bool TextProcessingEnabled + { + get + { + return 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() + { + (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed; + (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease; + (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput; + + _textChangedSubscription?.Dispose(); + _selectionStartChangedSubscription?.Dispose(); + _selectionEndtextChangedSubscription?.Dispose(); + + Dispatcher.UIThread.Post(() => + { + _hiddenTextBox.Clear(); + _parent.GlRenderer.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; + }); + } + } +} |