1 // Copyright 2016 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <functional> 9 #include <memory> 10 #include <optional> 11 #include <string> 12 #include <unordered_map> 13 #include <QKeySequence> 14 #include <QWidget> 15 #include "common/param_package.h" 16 #include "core/settings.h" 17 #include "input_common/main.h" 18 19 class QKeyEvent; 20 class QLabel; 21 class QPushButton; 22 class QSlider; 23 class QString; 24 class QTimer; 25 26 namespace Ui { 27 class ConfigureInput; 28 } 29 30 class ConfigureInput : public QWidget { 31 Q_OBJECT 32 33 public: 34 explicit ConfigureInput(QWidget* parent = nullptr); 35 ~ConfigureInput() override; 36 37 /// Save all button configurations to settings file 38 void ApplyConfiguration(); 39 void RetranslateUI(); 40 41 /// Load configuration settings. 42 void LoadConfiguration(); 43 void EmitInputKeysChanged(); 44 45 /// Save the current input profile index 46 void ApplyProfile(); 47 public slots: 48 void OnHotkeysChanged(QList<QKeySequence> new_key_list); 49 50 signals: 51 void InputKeysChanged(QList<QKeySequence> new_key_list); 52 53 private: 54 std::unique_ptr<Ui::ConfigureInput> ui; 55 56 std::unique_ptr<QTimer> timeout_timer; 57 std::unique_ptr<QTimer> poll_timer; 58 59 /// This will be the the setting function when an input is awaiting configuration. 60 std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; 61 62 std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param; 63 std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param; 64 65 static constexpr int ANALOG_SUB_BUTTONS_NUM = 5; 66 67 /// Each button input is represented by a QPushButton. 68 std::array<QPushButton*, Settings::NativeButton::NumButtons> button_map; 69 70 /// A group of five QPushButtons represent one analog input. The buttons each represent up, 71 /// down, left, right, and modifier, respectively. 72 std::array<std::array<QPushButton*, ANALOG_SUB_BUTTONS_NUM>, Settings::NativeAnalog::NumAnalogs> 73 analog_map_buttons; 74 75 /// Analog inputs are also represented each with a single button, used to configure with an 76 /// actual analog stick 77 std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick; 78 std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> 79 analog_map_deadzone_and_modifier_slider; 80 std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> 81 analog_map_deadzone_and_modifier_slider_label; 82 83 static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons; 84 85 std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; 86 87 /** 88 * List of keys currently registered to hotkeys. 89 * These can't be bound to any input key. 90 * Synchronised with ConfigureHotkeys via signal-slot. 91 */ 92 QList<QKeySequence> hotkey_list; 93 94 /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false, 95 /// keyboard events are ignored. 96 bool want_keyboard_keys = false; 97 98 /// Generates list of all used keys 99 QList<QKeySequence> GetUsedKeyboardKeys(); 100 101 void MapFromButton(const Common::ParamPackage& params); 102 void AutoMap(); 103 104 /// Restore all buttons to their default values. 105 void RestoreDefaults(); 106 /// Clear all input configuration 107 void ClearAll(); 108 109 /// Update UI to reflect current configuration. 110 void UpdateButtonLabels(); 111 112 /// Called when the button was pressed. 113 void HandleClick(QPushButton* button, 114 std::function<void(const Common::ParamPackage&)> new_input_setter, 115 InputCommon::Polling::DeviceType type); 116 117 /// The key code of the previous state of the key being currently bound. 118 int previous_key_code; 119 120 /// Finish polling and configure input using the input_setter 121 void SetPollingResult(const Common::ParamPackage& params, bool abort); 122 123 /// Handle key press events. 124 void keyPressEvent(QKeyEvent* event) override; 125 126 /// input profiles 127 void NewProfile(); 128 void DeleteProfile(); 129 void RenameProfile(); 130 131 bool IsProfileNameDuplicate(const QString& name) const; 132 void WarnProposedProfileNameIsDuplicate(); 133 }; 134