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/Input | |
| parent | 9ba73ffbe5f78c0403cf102b95768f388da05122 (diff) | |
Avalonia UI - Part 1 (#3270)
* 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/Input')
| -rw-r--r-- | Ryujinx.Ava/Input/AvaloniaKeyboard.cs | 205 | ||||
| -rw-r--r-- | Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs | 113 | ||||
| -rw-r--r-- | Ryujinx.Ava/Input/AvaloniaMappingHelper.cs | 188 | ||||
| -rw-r--r-- | Ryujinx.Ava/Input/AvaloniaMouse.cs | 90 | ||||
| -rw-r--r-- | Ryujinx.Ava/Input/AvaloniaMouseDriver.cs | 129 |
5 files changed, 725 insertions, 0 deletions
diff --git a/Ryujinx.Ava/Input/AvaloniaKeyboard.cs b/Ryujinx.Ava/Input/AvaloniaKeyboard.cs new file mode 100644 index 00000000..a75758b9 --- /dev/null +++ b/Ryujinx.Ava/Input/AvaloniaKeyboard.cs @@ -0,0 +1,205 @@ +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid.Keyboard; +using Ryujinx.Input; +using System; +using System.Collections.Generic; +using System.Numerics; + +using ConfigKey = Ryujinx.Common.Configuration.Hid.Key; +using Key = Ryujinx.Input.Key; + +namespace Ryujinx.Ava.Input +{ + public class AvaloniaKeyboard : IKeyboard + { + private readonly List<ButtonMappingEntry> _buttonsUserMapping; + private readonly AvaloniaKeyboardDriver _driver; + + private readonly object _userMappingLock = new(); + + private StandardKeyboardInputConfig _configuration; + + private bool HasConfiguration => _configuration != null; + + public string Id { get; } + public string Name { get; } + + public bool IsConnected => true; + + public GamepadFeaturesFlag Features => GamepadFeaturesFlag.None; + + public AvaloniaKeyboard(AvaloniaKeyboardDriver driver, string id, string name) + { + _driver = driver; + Id = id; + Name = name; + _buttonsUserMapping = new List<ButtonMappingEntry>(); + } + + public void Dispose() { } + + public KeyboardStateSnapshot GetKeyboardStateSnapshot() + { + return IKeyboard.GetStateSnapshot(this); + } + + public GamepadStateSnapshot GetMappedStateSnapshot() + { + KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot(); + GamepadStateSnapshot result = default; + + lock (_userMappingLock) + { + if (!HasConfiguration) + { + return result; + } + + foreach (ButtonMappingEntry entry in _buttonsUserMapping) + { + if (entry.From == Key.Unknown || entry.From == Key.Unbound || entry.To == GamepadButtonInputId.Unbound) + { + continue; + } + + // Do not touch state of the button already pressed + if (!result.IsPressed(entry.To)) + { + result.SetPressed(entry.To, rawState.IsPressed(entry.From)); + } + } + + (short leftStickX, short leftStickY) = GetStickValues(ref rawState, _configuration.LeftJoyconStick); + (short rightStickX, short rightStickY) = GetStickValues(ref rawState, _configuration.RightJoyconStick); + + result.SetStick(StickInputId.Left, ConvertRawStickValue(leftStickX), ConvertRawStickValue(leftStickY)); + result.SetStick(StickInputId.Right, ConvertRawStickValue(rightStickX), ConvertRawStickValue(rightStickY)); + } + + return result; + } + + public GamepadStateSnapshot GetStateSnapshot() + { + throw new NotSupportedException(); + } + + public (float, float) GetStick(StickInputId inputId) + { + throw new NotSupportedException(); + } + + public bool IsPressed(GamepadButtonInputId inputId) + { + throw new NotSupportedException(); + } + + public bool IsPressed(Key key) + { + try + { + return _driver.IsPressed(key); + } + catch + { + return false; + } + } + + public void SetConfiguration(InputConfig configuration) + { + lock (_userMappingLock) + { + _configuration = (StandardKeyboardInputConfig)configuration; + + _buttonsUserMapping.Clear(); + + // Left joycon + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftStick, (Key)_configuration.LeftJoyconStick.StickButton)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadUp, (Key)_configuration.LeftJoycon.DpadUp)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadDown, (Key)_configuration.LeftJoycon.DpadDown)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadLeft, (Key)_configuration.LeftJoycon.DpadLeft)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadRight, (Key)_configuration.LeftJoycon.DpadRight)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Minus, (Key)_configuration.LeftJoycon.ButtonMinus)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftShoulder, (Key)_configuration.LeftJoycon.ButtonL)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftTrigger, (Key)_configuration.LeftJoycon.ButtonZl)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger0, (Key)_configuration.LeftJoycon.ButtonSr)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger0, (Key)_configuration.LeftJoycon.ButtonSl)); + + // Finally right joycon + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightStick, (Key)_configuration.RightJoyconStick.StickButton)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.A, (Key)_configuration.RightJoycon.ButtonA)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.B, (Key)_configuration.RightJoycon.ButtonB)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.X, (Key)_configuration.RightJoycon.ButtonX)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Y, (Key)_configuration.RightJoycon.ButtonY)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Plus, (Key)_configuration.RightJoycon.ButtonPlus)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightShoulder, (Key)_configuration.RightJoycon.ButtonR)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightTrigger, (Key)_configuration.RightJoycon.ButtonZr)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger1, (Key)_configuration.RightJoycon.ButtonSr)); + _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, (Key)_configuration.RightJoycon.ButtonSl)); + } + } + + public void SetTriggerThreshold(float triggerThreshold) { } + + public void Rumble(float lowFrequency, float highFrequency, uint durationMs) { } + + public Vector3 GetMotionData(MotionInputId inputId) => Vector3.Zero; + + private static float ConvertRawStickValue(short value) + { + const float ConvertRate = 1.0f / (short.MaxValue + 0.5f); + + return value * ConvertRate; + } + + private static (short, short) GetStickValues(ref KeyboardStateSnapshot snapshot, JoyconConfigKeyboardStick<ConfigKey> stickConfig) + { + short stickX = 0; + short stickY = 0; + + if (snapshot.IsPressed((Key)stickConfig.StickUp)) + { + stickY += 1; + } + + if (snapshot.IsPressed((Key)stickConfig.StickDown)) + { + stickY -= 1; + } + + if (snapshot.IsPressed((Key)stickConfig.StickRight)) + { + stickX += 1; + } + + if (snapshot.IsPressed((Key)stickConfig.StickLeft)) + { + stickX -= 1; + } + + Vector2 stick = new(stickX, stickY); + + stick = Vector2.Normalize(stick); + + return ((short)(stick.X * short.MaxValue), (short)(stick.Y * short.MaxValue)); + } + + public void Clear() + { + _driver?.ResetKeys(); + } + + private class ButtonMappingEntry + { + public readonly Key From; + public readonly GamepadButtonInputId To; + + public ButtonMappingEntry(GamepadButtonInputId to, Key from) + { + To = to; + From = from; + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs b/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs new file mode 100644 index 00000000..3babfe9d --- /dev/null +++ b/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs @@ -0,0 +1,113 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Input; +using System; +using System.Collections.Generic; +using System.Linq; + +using AvaKey = Avalonia.Input.Key; +using Key = Ryujinx.Input.Key; +using TextInputEventArgs = OpenTK.Windowing.Common.TextInputEventArgs; + +namespace Ryujinx.Ava.Input +{ + public class AvaloniaKeyboardDriver : IGamepadDriver + { + private static readonly string[] _keyboardIdentifers = new string[1] { "0" }; + private readonly Control _control; + private readonly HashSet<AvaKey> _pressedKeys; + + public event EventHandler<KeyEventArgs> KeyPressed; + public event EventHandler<KeyEventArgs> KeyRelease; + public event EventHandler<TextInputEventArgs> TextInput; + + public string DriverName => "Avalonia"; + + public ReadOnlySpan<string> GamepadsIds => _keyboardIdentifers; + + public AvaloniaKeyboardDriver(Control control) + { + _control = control; + _pressedKeys = new HashSet<AvaKey>(); + + _control.KeyDown += OnKeyPress; + _control.KeyUp += OnKeyRelease; + _control.TextInput += Control_TextInput; + } + + private void Control_TextInput(object sender, Avalonia.Input.TextInputEventArgs e) + { + TextInput?.Invoke(this, new TextInputEventArgs(e.Text.First())); + } + + public event Action<string> OnGamepadConnected + { + add { } + remove { } + } + + public event Action<string> OnGamepadDisconnected + { + add { } + remove { } + } + + public void Dispose() + { + Dispose(true); + } + + public IGamepad GetGamepad(string id) + { + if (!_keyboardIdentifers[0].Equals(id)) + { + return null; + } + + return new AvaloniaKeyboard(this, _keyboardIdentifers[0], LocaleManager.Instance["AllKeyboards"]); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _control.KeyUp -= OnKeyPress; + _control.KeyDown -= OnKeyRelease; + } + } + + protected void OnKeyPress(object sender, KeyEventArgs args) + { + AvaKey key = args.Key; + + _pressedKeys.Add(args.Key); + + KeyPressed?.Invoke(this, args); + } + + protected void OnKeyRelease(object sender, KeyEventArgs args) + { + _pressedKeys.Remove(args.Key); + + KeyRelease?.Invoke(this, args); + } + + internal bool IsPressed(Key key) + { + if (key == Key.Unbound || key == Key.Unknown) + { + return false; + } + + AvaloniaMappingHelper.TryGetAvaKey(key, out var nativeKey); + + return _pressedKeys.Contains(nativeKey); + } + + public void ResetKeys() + { + _pressedKeys.Clear(); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/Input/AvaloniaMappingHelper.cs b/Ryujinx.Ava/Input/AvaloniaMappingHelper.cs new file mode 100644 index 00000000..b0aa2cc7 --- /dev/null +++ b/Ryujinx.Ava/Input/AvaloniaMappingHelper.cs @@ -0,0 +1,188 @@ +using Ryujinx.Input; +using System; +using System.Collections.Generic; +using AvaKey = Avalonia.Input.Key; + +namespace Ryujinx.Ava.Input +{ + public static class AvaloniaMappingHelper + { + private static readonly AvaKey[] _keyMapping = new AvaKey[(int)Key.Count] + { + // NOTE: Invalid + AvaKey.None, + + AvaKey.LeftShift, + AvaKey.RightShift, + AvaKey.LeftCtrl, + AvaKey.RightCtrl, + AvaKey.LeftAlt, + AvaKey.RightAlt, + AvaKey.LWin, + AvaKey.RWin, + AvaKey.Apps, + AvaKey.F1, + AvaKey.F2, + AvaKey.F3, + AvaKey.F4, + AvaKey.F5, + AvaKey.F6, + AvaKey.F7, + AvaKey.F8, + AvaKey.F9, + AvaKey.F10, + AvaKey.F11, + AvaKey.F12, + AvaKey.F13, + AvaKey.F14, + AvaKey.F15, + AvaKey.F16, + AvaKey.F17, + AvaKey.F18, + AvaKey.F19, + AvaKey.F20, + AvaKey.F21, + AvaKey.F22, + AvaKey.F23, + AvaKey.F24, + + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + AvaKey.None, + + AvaKey.Up, + AvaKey.Down, + AvaKey.Left, + AvaKey.Right, + AvaKey.Return, + AvaKey.Escape, + AvaKey.Space, + AvaKey.Tab, + AvaKey.Back, + AvaKey.Insert, + AvaKey.Delete, + AvaKey.PageUp, + AvaKey.PageDown, + AvaKey.Home, + AvaKey.End, + AvaKey.CapsLock, + AvaKey.Scroll, + AvaKey.Print, + AvaKey.Pause, + AvaKey.NumLock, + AvaKey.Clear, + AvaKey.NumPad0, + AvaKey.NumPad1, + AvaKey.NumPad2, + AvaKey.NumPad3, + AvaKey.NumPad4, + AvaKey.NumPad5, + AvaKey.NumPad6, + AvaKey.NumPad7, + AvaKey.NumPad8, + AvaKey.NumPad9, + AvaKey.Divide, + AvaKey.Multiply, + AvaKey.Subtract, + AvaKey.Add, + AvaKey.Decimal, + AvaKey.Enter, + AvaKey.A, + AvaKey.B, + AvaKey.C, + AvaKey.D, + AvaKey.E, + AvaKey.F, + AvaKey.G, + AvaKey.H, + AvaKey.I, + AvaKey.J, + AvaKey.K, + AvaKey.L, + AvaKey.M, + AvaKey.N, + AvaKey.O, + AvaKey.P, + AvaKey.Q, + AvaKey.R, + AvaKey.S, + AvaKey.T, + AvaKey.U, + AvaKey.V, + AvaKey.W, + AvaKey.X, + AvaKey.Y, + AvaKey.Z, + AvaKey.D0, + AvaKey.D1, + AvaKey.D2, + AvaKey.D3, + AvaKey.D4, + AvaKey.D5, + AvaKey.D6, + AvaKey.D7, + AvaKey.D8, + AvaKey.D9, + AvaKey.OemTilde, + AvaKey.OemTilde,AvaKey.OemMinus, + AvaKey.OemPlus, + AvaKey.OemOpenBrackets, + AvaKey.OemCloseBrackets, + AvaKey.OemSemicolon, + AvaKey.OemQuotes, + AvaKey.OemComma, + AvaKey.OemPeriod, + AvaKey.OemQuestion, + AvaKey.OemBackslash, + + // NOTE: invalid + AvaKey.None + }; + + private static readonly Dictionary<AvaKey, Key> _avaKeyMapping; + + static AvaloniaMappingHelper() + { + var inputKeys = Enum.GetValues(typeof(Key)); + + // Avalonia.Input.Key is not contiguous and quite large, so use a dictionary instead of an array. + _avaKeyMapping = new Dictionary<AvaKey, Key>(); + + foreach (var key in inputKeys) + { + if (TryGetAvaKey((Key)key, out var index)) + { + _avaKeyMapping[index] = (Key)key; + } + } + } + + public static bool TryGetAvaKey(Key key, out AvaKey avaKey) + { + var keyExist = (int)key < _keyMapping.Length; + if (keyExist) + { + avaKey = _keyMapping[(int)key]; + } + else + { + avaKey = AvaKey.None; + } + + return keyExist; + } + + public static Key ToInputKey(AvaKey key) + { + return _avaKeyMapping.GetValueOrDefault(key, Key.Unknown); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/Input/AvaloniaMouse.cs b/Ryujinx.Ava/Input/AvaloniaMouse.cs new file mode 100644 index 00000000..f3c2271b --- /dev/null +++ b/Ryujinx.Ava/Input/AvaloniaMouse.cs @@ -0,0 +1,90 @@ +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Input; +using System; +using System.Drawing; +using System.Numerics; + +namespace Ryujinx.Ava.Input +{ + public class AvaloniaMouse : IMouse + { + private AvaloniaMouseDriver _driver; + + public GamepadFeaturesFlag Features => throw new NotImplementedException(); + + public string Id => "0"; + + public string Name => "AvaloniaMouse"; + + public bool IsConnected => true; + + public bool[] Buttons => _driver.PressedButtons; + + public AvaloniaMouse(AvaloniaMouseDriver driver) + { + _driver = driver; + } + + public Size ClientSize => _driver.GetClientSize(); + + public Vector2 GetPosition() + { + return _driver.CurrentPosition; + } + + public Vector2 GetScroll() + { + return _driver.Scroll; + } + + public GamepadStateSnapshot GetMappedStateSnapshot() + { + throw new NotImplementedException(); + } + + public Vector3 GetMotionData(MotionInputId inputId) + { + throw new NotImplementedException(); + } + + public GamepadStateSnapshot GetStateSnapshot() + { + throw new NotImplementedException(); + } + + public (float, float) GetStick(StickInputId inputId) + { + throw new NotImplementedException(); + } + + public bool IsButtonPressed(MouseButton button) + { + return _driver.IsButtonPressed(button); + } + + public bool IsPressed(GamepadButtonInputId inputId) + { + throw new NotImplementedException(); + } + + public void Rumble(float lowFrequency, float highFrequency, uint durationMs) + { + throw new NotImplementedException(); + } + + public void SetConfiguration(InputConfig configuration) + { + throw new NotImplementedException(); + } + + public void SetTriggerThreshold(float triggerThreshold) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + _driver = null; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs b/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs new file mode 100644 index 00000000..5a9fe791 --- /dev/null +++ b/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs @@ -0,0 +1,129 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Threading; +using Ryujinx.Input; +using System; +using System.Numerics; +using MouseButton = Ryujinx.Input.MouseButton; +using Size = System.Drawing.Size; + +namespace Ryujinx.Ava.Input +{ + public class AvaloniaMouseDriver : IGamepadDriver + { + private Control _widget; + private bool _isDisposed; + + public bool[] PressedButtons { get; } + + public Vector2 CurrentPosition { get; private set; } + public Vector2 Scroll { get; private set; } + + public AvaloniaMouseDriver(Control parent) + { + _widget = parent; + + _widget.PointerMoved += Parent_PointerMovedEvent; + _widget.PointerPressed += Parent_PointerPressEvent; + _widget.PointerReleased += Parent_PointerReleaseEvent; + _widget.PointerWheelChanged += Parent_ScrollEvent; + + PressedButtons = new bool[(int)MouseButton.Count]; + } + + private void Parent_ScrollEvent(object o, PointerWheelEventArgs args) + { + Scroll = new Vector2((float)args.Delta.X, (float)args.Delta.Y); + } + + private void Parent_PointerReleaseEvent(object o, PointerReleasedEventArgs args) + { + var pointerProperties = args.GetCurrentPoint(_widget).Properties; + PressedButtons[(int)args.InitialPressMouseButton - 1] = false; + } + + private void Parent_PointerPressEvent(object o, PointerPressedEventArgs args) + { + var pointerProperties = args.GetCurrentPoint(_widget).Properties; + + PressedButtons[(int)pointerProperties.PointerUpdateKind] = true; + } + + private void Parent_PointerMovedEvent(object o, PointerEventArgs args) + { + var position = args.GetPosition(_widget); + + CurrentPosition = new Vector2((float)position.X, (float)position.Y); + } + + public void SetMousePressed(MouseButton button) + { + PressedButtons[(int)button] = true; + } + + public void SetMouseReleased(MouseButton button) + { + PressedButtons[(int)button] = false; + } + + public void SetPosition(double x, double y) + { + CurrentPosition = new Vector2((float)x, (float)y); + } + + public bool IsButtonPressed(MouseButton button) + { + return PressedButtons[(int)button]; + } + + public Size GetClientSize() + { + Size size = new(); + + Dispatcher.UIThread.InvokeAsync(() => + { + size = new Size((int)_widget.Bounds.Width, (int)_widget.Bounds.Height); + }).Wait(); + + return size; + } + + public string DriverName => "Avalonia"; + + public event Action<string> OnGamepadConnected + { + add { } + remove { } + } + + public event Action<string> OnGamepadDisconnected + { + add { } + remove { } + } + + public ReadOnlySpan<string> GamepadsIds => new[] { "0" }; + + public IGamepad GetGamepad(string id) + { + return new AvaloniaMouse(this); + } + + public void Dispose() + { + if (_isDisposed) + { + return; + } + + _isDisposed = true; + + _widget.PointerMoved -= Parent_PointerMovedEvent; + _widget.PointerPressed -= Parent_PointerPressEvent; + _widget.PointerReleased -= Parent_PointerReleaseEvent; + _widget.PointerWheelChanged -= Parent_ScrollEvent; + + _widget = null; + } + } +}
\ No newline at end of file |
