public async void GetInputAndAssign(IButtonAssigner assigner, IKeyboard keyboard = null) { Dispatcher.UIThread.Post(() => { ToggledButton.IsChecked = true; }); if (_isWaitingForInput) { Dispatcher.UIThread.Post(() => { Cancel(); }); return; } _isWaitingForInput = true; assigner.Initialize(); await Task.Run(async() => { while (true) { if (!_isWaitingForInput) { return; } await Task.Delay(10); assigner.ReadInput(); if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape))) { break; } } }); await Dispatcher.UIThread.InvokeAsync(() => { string pressedButton = assigner.GetPressedButton(); if (_shouldUnbind) { SetButtonText(ToggledButton, "Unbound"); } else if (pressedButton != "") { SetButtonText(ToggledButton, pressedButton); } _shouldUnbind = false; _isWaitingForInput = false; ToggledButton.IsChecked = false; ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
private void Button_Checked(object sender, RoutedEventArgs e) { if (sender is ToggleButton button) { if (_currentAssigner != null && button == _currentAssigner.ToggledButton) { return; } bool isStick = button.Tag != null && button.Tag.ToString() == "stick"; if (_currentAssigner == null && (bool)button.IsChecked) { _currentAssigner = new ButtonKeyAssigner(button); FocusManager.Instance.Focus(this, NavigationMethod.Pointer); PointerPressed += MouseClick; IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations. IButtonAssigner assigner = CreateButtonAssigner(isStick); _currentAssigner.ButtonAssigned += (sender, e) => { if (e.IsAssigned) { ViewModel.IsModified = true; } }; _currentAssigner.GetInputAndAssign(assigner, keyboard); } else { if (_currentAssigner != null) { ToggleButton oldButton = _currentAssigner.ToggledButton; _currentAssigner.Cancel(); _currentAssigner = null; button.IsChecked = false; } } } }