Consolidate most logic into StickVisualizer
.
This commit is contained in:
parent
de08974f82
commit
40625f395a
6 changed files with 233 additions and 196 deletions
|
@ -1,10 +1,13 @@
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
|
using Ryujinx.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models.Input
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
{
|
{
|
||||||
public class StickVisualizer : BaseModel
|
public class StickVisualizer : BaseModel, IDisposable
|
||||||
{
|
{
|
||||||
public const int DrawStickPollRate = 50; // Milliseconds per poll.
|
public const int DrawStickPollRate = 50; // Milliseconds per poll.
|
||||||
public const int DrawStickCircumference = 5;
|
public const int DrawStickCircumference = 5;
|
||||||
|
@ -14,12 +17,26 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
||||||
public const float MaxVectorLength = DrawStickCanvasSize / 2;
|
public const float MaxVectorLength = DrawStickCanvasSize / 2;
|
||||||
|
|
||||||
public CancellationTokenSource PollTokenSource = new();
|
public CancellationTokenSource PollTokenSource;
|
||||||
public CancellationToken PollToken;
|
public CancellationToken PollToken;
|
||||||
|
|
||||||
private static float _vectorLength;
|
private static float _vectorLength;
|
||||||
private static float _vectorMultiplier;
|
private static float _vectorMultiplier;
|
||||||
|
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
private DeviceType _type;
|
||||||
|
public DeviceType Type
|
||||||
|
{
|
||||||
|
get => _type;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private GamepadInputConfig _gamepadConfig;
|
private GamepadInputConfig _gamepadConfig;
|
||||||
public GamepadInputConfig GamepadConfig
|
public GamepadInputConfig GamepadConfig
|
||||||
{
|
{
|
||||||
|
@ -86,22 +103,119 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
|
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
|
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
|
|
||||||
|
private InputViewModel Parent;
|
||||||
|
|
||||||
|
public StickVisualizer(InputViewModel parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
PollTokenSource = new CancellationTokenSource();
|
||||||
|
PollToken = PollTokenSource.Token;
|
||||||
|
|
||||||
|
Task.Run(Initialize, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateConfig(object config)
|
public void UpdateConfig(object config)
|
||||||
{
|
{
|
||||||
if (config is GamepadInputConfig padConfig)
|
if (config is ControllerInputViewModel padConfig)
|
||||||
{
|
{
|
||||||
GamepadConfig = padConfig;
|
GamepadConfig = padConfig.Config;
|
||||||
|
Type = DeviceType.Controller;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (config is KeyboardInputConfig keyConfig)
|
else if (config is KeyboardInputViewModel keyConfig)
|
||||||
{
|
{
|
||||||
KeyboardConfig = keyConfig;
|
KeyboardConfig = keyConfig.Config;
|
||||||
|
Type = DeviceType.Keyboard;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ArgumentException($"Invalid configuration: {config}");
|
Type = DeviceType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Initialize()
|
||||||
|
{
|
||||||
|
(float, float) leftBuffer;
|
||||||
|
(float, float) rightBuffer;
|
||||||
|
|
||||||
|
while (!PollToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
leftBuffer = (0f, 0f);
|
||||||
|
rightBuffer = (0f, 0f);
|
||||||
|
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case DeviceType.Keyboard:
|
||||||
|
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
|
||||||
|
|
||||||
|
if (keyboard != null)
|
||||||
|
{
|
||||||
|
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.Controller:
|
||||||
|
IGamepad controller = Parent.SelectedGamepad;
|
||||||
|
|
||||||
|
if (controller != null)
|
||||||
|
{
|
||||||
|
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
|
||||||
|
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
|
||||||
|
await Task.Delay(DrawStickPollRate, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
PollTokenSource.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (float, float) ClampVector((float, float) vect)
|
public static (float, float) ClampVector((float, float) vect)
|
||||||
|
@ -119,5 +233,28 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
|
|
||||||
return vect;
|
return vect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
PollTokenSource.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardConfig = null;
|
||||||
|
GamepadConfig = null;
|
||||||
|
Parent = null;
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,11 @@
|
||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
using Ryujinx.Ava.Input;
|
|
||||||
using Ryujinx.Ava.UI.Models.Input;
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
using Ryujinx.Ava.UI.Views.Input;
|
using Ryujinx.Ava.UI.Views.Input;
|
||||||
using Ryujinx.Input;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class ControllerInputViewModel : BaseModel
|
public class ControllerInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private IGamepad _selectedGamepad;
|
|
||||||
|
|
||||||
private StickVisualizer _stickVisualizer;
|
|
||||||
public StickVisualizer StickVisualizer
|
|
||||||
{
|
|
||||||
get => _stickVisualizer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_stickVisualizer = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private GamepadInputConfig _config;
|
private GamepadInputConfig _config;
|
||||||
public GamepadInputConfig Config
|
public GamepadInputConfig Config
|
||||||
{
|
{
|
||||||
|
@ -31,7 +13,18 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_config = value;
|
_config = value;
|
||||||
StickVisualizer.UpdateConfig(Config);
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StickVisualizer _visualizer;
|
||||||
|
public StickVisualizer Visualizer
|
||||||
|
{
|
||||||
|
get => _visualizer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_visualizer = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
|
@ -76,17 +69,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
|
||||||
{
|
{
|
||||||
ParentModel = model;
|
ParentModel = model;
|
||||||
|
Visualizer = visualizer;
|
||||||
model.NotifyChangesEvent += OnParentModelChanged;
|
model.NotifyChangesEvent += OnParentModelChanged;
|
||||||
OnParentModelChanged();
|
OnParentModelChanged();
|
||||||
_stickVisualizer = new();
|
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|
||||||
StickVisualizer.PollToken = StickVisualizer.PollTokenSource.Token;
|
|
||||||
|
|
||||||
Task.Run(() => PollSticks(StickVisualizer.PollToken));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void ShowMotionConfig()
|
public async void ShowMotionConfig()
|
||||||
|
@ -99,24 +88,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
await RumbleInputView.Show(this);
|
await RumbleInputView.Show(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PollSticks(CancellationToken token)
|
|
||||||
{
|
|
||||||
while (!token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
_selectedGamepad = ParentModel.SelectedGamepad;
|
|
||||||
|
|
||||||
if (_selectedGamepad != null && _selectedGamepad is not AvaloniaKeyboard)
|
|
||||||
{
|
|
||||||
StickVisualizer.UiStickLeft = _selectedGamepad.GetStick(StickInputId.Left);
|
|
||||||
StickVisualizer.UiStickRight = _selectedGamepad.GetStick(StickInputId.Right);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(StickVisualizer.DrawStickPollRate, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
StickVisualizer.PollTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnParentModelChanged()
|
public void OnParentModelChanged()
|
||||||
{
|
{
|
||||||
IsLeft = ParentModel.IsLeft;
|
IsLeft = ParentModel.IsLeft;
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
public IGamepadDriver AvaloniaKeyboardDriver { get; }
|
public IGamepadDriver AvaloniaKeyboardDriver { get; }
|
||||||
public IGamepad SelectedGamepad { get; private set; }
|
public IGamepad SelectedGamepad { get; private set; }
|
||||||
|
public StickVisualizer VisualStick { get; private set; }
|
||||||
|
|
||||||
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
|
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
|
||||||
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
|
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
|
||||||
|
@ -80,6 +81,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
_configViewModel = value;
|
_configViewModel = value;
|
||||||
|
|
||||||
|
VisualStick.UpdateConfig(value);
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,6 +264,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
Devices = new ObservableCollection<(DeviceType Type, string Id, string Name)>();
|
Devices = new ObservableCollection<(DeviceType Type, string Id, string Name)>();
|
||||||
ProfilesList = new AvaloniaList<string>();
|
ProfilesList = new AvaloniaList<string>();
|
||||||
DeviceList = new AvaloniaList<string>();
|
DeviceList = new AvaloniaList<string>();
|
||||||
|
VisualStick = new StickVisualizer(this);
|
||||||
|
|
||||||
ControllerImage = ProControllerResource;
|
ControllerImage = ProControllerResource;
|
||||||
|
|
||||||
|
@ -281,12 +285,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
||||||
{
|
{
|
||||||
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
|
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig), VisualStick);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config is StandardControllerInputConfig controllerInputConfig)
|
if (Config is StandardControllerInputConfig controllerInputConfig)
|
||||||
{
|
{
|
||||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
|
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,10 +883,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
|
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
|
||||||
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
|
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
|
||||||
|
|
||||||
(ConfigViewModel as ControllerInputViewModel)?.StickVisualizer.PollTokenSource.Cancel();
|
|
||||||
|
|
||||||
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
||||||
|
|
||||||
|
VisualStick.Dispose();
|
||||||
|
|
||||||
SelectedGamepad?.Dispose();
|
SelectedGamepad?.Dispose();
|
||||||
|
|
||||||
AvaloniaKeyboardDriver.Dispose();
|
AvaloniaKeyboardDriver.Dispose();
|
||||||
|
|
|
@ -1,27 +1,10 @@
|
||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
using Ryujinx.Ava.UI.Models.Input;
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
using Ryujinx.Input;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class KeyboardInputViewModel : BaseModel
|
public class KeyboardInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private (float, float) _leftBuffer = (0, 0);
|
|
||||||
private (float, float) _rightBuffer = (0, 0);
|
|
||||||
private StickVisualizer _stickVisualizer;
|
|
||||||
public StickVisualizer StickVisualizer
|
|
||||||
{
|
|
||||||
get => _stickVisualizer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_stickVisualizer = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private KeyboardInputConfig _config;
|
private KeyboardInputConfig _config;
|
||||||
public KeyboardInputConfig Config
|
public KeyboardInputConfig Config
|
||||||
{
|
{
|
||||||
|
@ -29,7 +12,18 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_config = value;
|
_config = value;
|
||||||
StickVisualizer.UpdateConfig(_config);
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StickVisualizer _visualizer;
|
||||||
|
public StickVisualizer Visualizer
|
||||||
|
{
|
||||||
|
get => _visualizer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_visualizer = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
|
@ -74,70 +68,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
|
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
|
||||||
{
|
{
|
||||||
ParentModel = model;
|
ParentModel = model;
|
||||||
|
Visualizer = visualizer;
|
||||||
model.NotifyChangesEvent += OnParentModelChanged;
|
model.NotifyChangesEvent += OnParentModelChanged;
|
||||||
OnParentModelChanged();
|
OnParentModelChanged();
|
||||||
_stickVisualizer = new();
|
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|
||||||
StickVisualizer.PollToken = StickVisualizer.PollTokenSource.Token;
|
|
||||||
|
|
||||||
Task.Run(() => PollKeyboard(StickVisualizer.PollToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task PollKeyboard(CancellationToken token)
|
|
||||||
{
|
|
||||||
while (!token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
if (ParentModel.IsKeyboard)
|
|
||||||
{
|
|
||||||
IKeyboard keyboard = (IKeyboard)ParentModel.AvaloniaKeyboardDriver.GetGamepad("0");
|
|
||||||
var snap = keyboard.GetKeyboardStateSnapshot();
|
|
||||||
|
|
||||||
if (snap.IsPressed((Key)Config.LeftStickRight))
|
|
||||||
{
|
|
||||||
_leftBuffer.Item1 += 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.LeftStickLeft))
|
|
||||||
{
|
|
||||||
_leftBuffer.Item1 -= 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.LeftStickUp))
|
|
||||||
{
|
|
||||||
_leftBuffer.Item2 += 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.LeftStickDown))
|
|
||||||
{
|
|
||||||
_leftBuffer.Item2 -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snap.IsPressed((Key)Config.RightStickRight))
|
|
||||||
{
|
|
||||||
_rightBuffer.Item1 += 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.RightStickLeft))
|
|
||||||
{
|
|
||||||
_rightBuffer.Item1 -= 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.RightStickUp))
|
|
||||||
{
|
|
||||||
_rightBuffer.Item2 += 1;
|
|
||||||
}
|
|
||||||
if (snap.IsPressed((Key)Config.RightStickDown))
|
|
||||||
{
|
|
||||||
_rightBuffer.Item2 -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
StickVisualizer.UiStickLeft = _leftBuffer;
|
|
||||||
StickVisualizer.UiStickRight = _rightBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(StickVisualizer.DrawStickPollRate, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
StickVisualizer.PollTokenSource.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnParentModelChanged()
|
public void OnParentModelChanged()
|
||||||
|
|
|
@ -333,72 +333,72 @@
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
Height="{Binding StickVisualizer.UiStickBorderSize}"
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
Width="{Binding StickVisualizer.UiStickBorderSize}"
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
IsVisible="{Binding IsLeft}">
|
IsVisible="{Binding IsLeft}">
|
||||||
<Canvas
|
<Canvas
|
||||||
Background="{DynamicResource ThemeBackgroundColor}"
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}">
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
<Grid
|
<Grid
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Background="{DynamicResource ThemeBackgroundColor}">
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Stroke="Black"
|
Stroke="Black"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"/>
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Fill="Gray"
|
Fill="Gray"
|
||||||
Opacity="100"
|
Opacity="100"
|
||||||
Height="{Binding StickVisualizer.UiDeadzoneLeft}"
|
Height="{Binding Visualizer.UiDeadzoneLeft}"
|
||||||
Width="{Binding StickVisualizer.UiDeadzoneLeft}"/>
|
Width="{Binding Visualizer.UiDeadzoneLeft}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
Fill="Red"
|
Fill="Red"
|
||||||
Width="{Binding StickVisualizer.UiStickCircumference}"
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
Height="{Binding StickVisualizer.UiStickCircumference}"
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
Canvas.Bottom="{Binding StickVisualizer.UiStickLeftY}"
|
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||||
Canvas.Left="{Binding StickVisualizer.UiStickLeftX}" />
|
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
Height="{Binding StickVisualizer.UiStickBorderSize}"
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
Width="{Binding StickVisualizer.UiStickBorderSize}"
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
IsVisible="{Binding IsRight}">
|
IsVisible="{Binding IsRight}">
|
||||||
<Canvas
|
<Canvas
|
||||||
Background="{DynamicResource ThemeBackgroundColor}"
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}">
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
<Grid
|
<Grid
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Background="{DynamicResource ThemeBackgroundColor}">
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Stroke="Black"
|
Stroke="Black"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"/>
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Fill="Gray"
|
Fill="Gray"
|
||||||
Opacity="100"
|
Opacity="100"
|
||||||
Height="{Binding StickVisualizer.UiDeadzoneRight}"
|
Height="{Binding Visualizer.UiDeadzoneRight}"
|
||||||
Width="{Binding StickVisualizer.UiDeadzoneRight}"/>
|
Width="{Binding Visualizer.UiDeadzoneRight}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
Fill="Red"
|
Fill="Red"
|
||||||
Width="{Binding StickVisualizer.UiStickCircumference}"
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
Height="{Binding StickVisualizer.UiStickCircumference}"
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
Canvas.Bottom="{Binding StickVisualizer.UiStickRightY}"
|
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||||
Canvas.Left="{Binding StickVisualizer.UiStickRightX}" />
|
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
|
@ -327,72 +327,60 @@
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
Height="{Binding StickVisualizer.UiStickBorderSize}"
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
Width="{Binding StickVisualizer.UiStickBorderSize}"
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
IsVisible="{Binding IsLeft}">
|
IsVisible="{Binding IsLeft}">
|
||||||
<Canvas
|
<Canvas
|
||||||
Background="{DynamicResource ThemeBackgroundColor}"
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}">
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
<Grid
|
<Grid
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Background="{DynamicResource ThemeBackgroundColor}">
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Stroke="Black"
|
Stroke="Black"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"/>
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
<Ellipse
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
Fill="Gray"
|
|
||||||
Opacity="100"
|
|
||||||
Height="{Binding StickVisualizer.UiDeadzoneLeft}"
|
|
||||||
Width="{Binding StickVisualizer.UiDeadzoneLeft}"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
Fill="Red"
|
Fill="Red"
|
||||||
Width="{Binding StickVisualizer.UiStickCircumference}"
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
Height="{Binding StickVisualizer.UiStickCircumference}"
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
Canvas.Bottom="{Binding StickVisualizer.UiStickLeftY}"
|
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||||
Canvas.Left="{Binding StickVisualizer.UiStickLeftX}" />
|
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
Height="{Binding StickVisualizer.UiStickBorderSize}"
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
Width="{Binding StickVisualizer.UiStickBorderSize}"
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
IsVisible="{Binding IsRight}">
|
IsVisible="{Binding IsRight}">
|
||||||
<Canvas
|
<Canvas
|
||||||
Background="{DynamicResource ThemeBackgroundColor}"
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}">
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
<Grid
|
<Grid
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Background="{DynamicResource ThemeBackgroundColor}">
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Stroke="Black"
|
Stroke="Black"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Width="{Binding StickVisualizer.UiCanvasSize}"
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
Height="{Binding StickVisualizer.UiCanvasSize}"/>
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
<Ellipse
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
Fill="Gray"
|
|
||||||
Opacity="100"
|
|
||||||
Height="{Binding StickVisualizer.UiDeadzoneRight}"
|
|
||||||
Width="{Binding StickVisualizer.UiDeadzoneRight}"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Ellipse
|
<Ellipse
|
||||||
Fill="Red"
|
Fill="Red"
|
||||||
Width="{Binding StickVisualizer.UiStickCircumference}"
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
Height="{Binding StickVisualizer.UiStickCircumference}"
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
Canvas.Bottom="{Binding StickVisualizer.UiStickRightY}"
|
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||||
Canvas.Left="{Binding StickVisualizer.UiStickRightX}" />
|
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -751,4 +739,4 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
Loading…
Reference in a new issue