aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ava/Input
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.Ava/Input
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.Ava/Input')
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs201
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs115
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs185
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaMouse.cs87
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs161
5 files changed, 749 insertions, 0 deletions
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs
new file mode 100644
index 00000000..d40ebbd2
--- /dev/null
+++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs
@@ -0,0 +1,201 @@
+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
+{
+ internal class AvaloniaKeyboard : IKeyboard
+ {
+ private readonly List<ButtonMappingEntry> _buttonsUserMapping;
+ private readonly AvaloniaKeyboardDriver _driver;
+ private StandardKeyboardInputConfig _configuration;
+
+ private readonly object _userMappingLock = new();
+
+ public string Id { get; }
+ public string Name { get; }
+
+ public bool IsConnected => true;
+ public GamepadFeaturesFlag Features => GamepadFeaturesFlag.None;
+
+ private class ButtonMappingEntry
+ {
+ public readonly Key From;
+ public readonly GamepadButtonInputId To;
+
+ public ButtonMappingEntry(GamepadButtonInputId to, Key from)
+ {
+ To = to;
+ From = from;
+ }
+ }
+
+ public AvaloniaKeyboard(AvaloniaKeyboardDriver driver, string id, string name)
+ {
+ _buttonsUserMapping = new List<ButtonMappingEntry>();
+
+ _driver = driver;
+ Id = id;
+ Name = name;
+ }
+
+ public KeyboardStateSnapshot GetKeyboardStateSnapshot()
+ {
+ return IKeyboard.GetStateSnapshot(this);
+ }
+
+ public GamepadStateSnapshot GetMappedStateSnapshot()
+ {
+ KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot();
+ GamepadStateSnapshot result = default;
+
+ lock (_userMappingLock)
+ {
+ if (_configuration == null)
+ {
+ return result;
+ }
+
+ foreach (ButtonMappingEntry entry in _buttonsUserMapping)
+ {
+ if (entry.From == Key.Unknown || entry.From == Key.Unbound || entry.To == GamepadButtonInputId.Unbound)
+ {
+ continue;
+ }
+
+ // NOTE: 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));
+
+ // 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();
+ }
+
+ public void Dispose() { }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
new file mode 100644
index 00000000..edcdb52f
--- /dev/null
+++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
@@ -0,0 +1,115 @@
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Input;
+using System;
+using System.Collections.Generic;
+using AvaKey = Avalonia.Input.Key;
+using Key = Ryujinx.Input.Key;
+
+namespace Ryujinx.Ava.Input
+{
+ internal 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<string> TextInput;
+
+ public string DriverName => "AvaloniaKeyboardDriver";
+ 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;
+ _control.AddHandler(InputElement.TextInputEvent, Control_LastChanceTextInput, RoutingStrategies.Bubble);
+ }
+
+ private void Control_TextInput(object sender, TextInputEventArgs e)
+ {
+ TextInput?.Invoke(this, e.Text);
+ }
+
+ private void Control_LastChanceTextInput(object sender, TextInputEventArgs e)
+ {
+ // Swallow event
+ e.Handled = true;
+ }
+
+ public event Action<string> OnGamepadConnected
+ {
+ add { }
+ remove { }
+ }
+
+ public event Action<string> OnGamepadDisconnected
+ {
+ add { }
+ remove { }
+ }
+
+ public IGamepad GetGamepad(string id)
+ {
+ if (!_keyboardIdentifers[0].Equals(id))
+ {
+ return null;
+ }
+
+ return new AvaloniaKeyboard(this, _keyboardIdentifers[0], LocaleManager.Instance[LocaleKeys.AllKeyboards]);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _control.KeyUp -= OnKeyPress;
+ _control.KeyDown -= OnKeyRelease;
+ }
+ }
+
+ protected void OnKeyPress(object sender, KeyEventArgs args)
+ {
+ _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;
+ }
+
+ AvaloniaKeyboardMappingHelper.TryGetAvaKey(key, out var nativeKey);
+
+ return _pressedKeys.Contains(nativeKey);
+ }
+
+ public void ResetKeys()
+ {
+ _pressedKeys.Clear();
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs
new file mode 100644
index 00000000..0cc04d0a
--- /dev/null
+++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs
@@ -0,0 +1,185 @@
+using Ryujinx.Input;
+using System;
+using System.Collections.Generic;
+using AvaKey = Avalonia.Input.Key;
+
+namespace Ryujinx.Ava.Input
+{
+ internal static class AvaloniaKeyboardMappingHelper
+ {
+ private static readonly AvaKey[] _keyMapping = {
+ // 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 AvaloniaKeyboardMappingHelper()
+ {
+ var inputKeys = Enum.GetValues<Key>();
+
+ // NOTE: 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, out var index))
+ {
+ _avaKeyMapping[index] = key;
+ }
+ }
+ }
+
+ public static bool TryGetAvaKey(Key key, out AvaKey avaKey)
+ {
+ avaKey = AvaKey.None;
+
+ bool keyExist = (int)key < _keyMapping.Length;
+ if (keyExist)
+ {
+ avaKey = _keyMapping[(int)key];
+ }
+
+ return keyExist;
+ }
+
+ public static Key ToInputKey(AvaKey key)
+ {
+ return _avaKeyMapping.GetValueOrDefault(key, Key.Unknown);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Input/AvaloniaMouse.cs b/src/Ryujinx.Ava/Input/AvaloniaMouse.cs
new file mode 100644
index 00000000..3a9c91c0
--- /dev/null
+++ b/src/Ryujinx.Ava/Input/AvaloniaMouse.cs
@@ -0,0 +1,87 @@
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Input;
+using System;
+using System.Drawing;
+using System.Numerics;
+
+namespace Ryujinx.Ava.Input
+{
+ internal class AvaloniaMouse : IMouse
+ {
+ private AvaloniaMouseDriver _driver;
+
+ public string Id => "0";
+ public string Name => "AvaloniaMouse";
+
+ public bool IsConnected => true;
+ public GamepadFeaturesFlag Features => throw new NotImplementedException();
+ 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/src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs b/src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs
new file mode 100644
index 00000000..b3e1a21a
--- /dev/null
+++ b/src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs
@@ -0,0 +1,161 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Input;
+using FluentAvalonia.Core;
+using Ryujinx.Input;
+using System;
+using System.Numerics;
+using MouseButton = Ryujinx.Input.MouseButton;
+using Size = System.Drawing.Size;
+
+namespace Ryujinx.Ava.Input
+{
+ internal class AvaloniaMouseDriver : IGamepadDriver
+ {
+ private Control _widget;
+ private bool _isDisposed;
+ private Size _size;
+ private readonly TopLevel _window;
+
+ public bool[] PressedButtons { get; }
+ public Vector2 CurrentPosition { get; private set; }
+ public Vector2 Scroll { get; private set; }
+
+ public string DriverName => "AvaloniaMouseDriver";
+ public ReadOnlySpan<string> GamepadsIds => new[] { "0" };
+
+ public AvaloniaMouseDriver(TopLevel window, Control parent)
+ {
+ _widget = parent;
+ _window = window;
+
+ _widget.PointerMoved += Parent_PointerMovedEvent;
+ _widget.PointerPressed += Parent_PointerPressEvent;
+ _widget.PointerReleased += Parent_PointerReleaseEvent;
+ _widget.PointerWheelChanged += Parent_ScrollEvent;
+
+ _window.PointerMoved += Parent_PointerMovedEvent;
+ _window.PointerPressed += Parent_PointerPressEvent;
+ _window.PointerReleased += Parent_PointerReleaseEvent;
+ _window.PointerWheelChanged += Parent_ScrollEvent;
+
+ PressedButtons = new bool[(int)MouseButton.Count];
+
+ _size = new Size((int)parent.Bounds.Width, (int)parent.Bounds.Height);
+
+ parent.GetObservable(Visual.BoundsProperty).Subscribe(Resized);
+ }
+
+ public event Action<string> OnGamepadConnected
+ {
+ add { }
+ remove { }
+ }
+
+ public event Action<string> OnGamepadDisconnected
+ {
+ add { }
+ remove { }
+ }
+
+ private void Resized(Rect rect)
+ {
+ _size = new Size((int)rect.Width, (int)rect.Height);
+ }
+
+ 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)
+ {
+ int button = (int)args.InitialPressMouseButton - 1;
+
+ if (PressedButtons.Count() >= button)
+ {
+ PressedButtons[button] = false;
+ }
+ }
+
+ private void Parent_PointerPressEvent(object o, PointerPressedEventArgs args)
+ {
+ int button = (int)args.GetCurrentPoint(_widget).Properties.PointerUpdateKind;
+
+ if (PressedButtons.Count() >= button)
+ {
+ PressedButtons[button] = true;
+ }
+ }
+
+ private void Parent_PointerMovedEvent(object o, PointerEventArgs args)
+ {
+ Point position = args.GetPosition(_widget);
+
+ CurrentPosition = new Vector2((float)position.X, (float)position.Y);
+ }
+
+ public void SetMousePressed(MouseButton button)
+ {
+ if (PressedButtons.Count() >= (int)button)
+ {
+ PressedButtons[(int)button] = true;
+ }
+ }
+
+ public void SetMouseReleased(MouseButton button)
+ {
+ if (PressedButtons.Count() >= (int)button)
+ {
+ PressedButtons[(int)button] = false;
+ }
+ }
+
+ public void SetPosition(double x, double y)
+ {
+ CurrentPosition = new Vector2((float)x, (float)y);
+ }
+
+ public bool IsButtonPressed(MouseButton button)
+ {
+ if (PressedButtons.Count() >= (int)button)
+ {
+ return PressedButtons[(int)button];
+ }
+
+ return false;
+ }
+
+ public Size GetClientSize()
+ {
+ return _size;
+ }
+
+ 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;
+
+ _window.PointerMoved -= Parent_PointerMovedEvent;
+ _window.PointerPressed -= Parent_PointerPressEvent;
+ _window.PointerReleased -= Parent_PointerReleaseEvent;
+ _window.PointerWheelChanged -= Parent_ScrollEvent;
+
+ _widget = null;
+ }
+ }
+} \ No newline at end of file