citra_qt/configuration: misc input tab improvements
* Added a context menu on the buttons including Clear & Restore Default * Allow clearing (unsetting) inputs. Added a Clear All button * Allow restoring a single input to default (instead of all)
This commit is contained in:
		| @@ -20,7 +20,15 @@ constexpr char KEY_VALUE_SEPARATOR_ESCAPE[] = "$0"; | ||||
| constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1"; | ||||
| constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2"; | ||||
|  | ||||
| /// A placeholder for empty param packages to avoid empty strings | ||||
| /// (they may be recognized as "not set" by some frontend libraries like qt) | ||||
| constexpr char EMPTY_PLACEHOLDER[] = "[empty]"; | ||||
|  | ||||
| ParamPackage::ParamPackage(const std::string& serialized) { | ||||
|     if (serialized == EMPTY_PLACEHOLDER) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::vector<std::string> pairs; | ||||
|     Common::SplitString(serialized, PARAM_SEPARATOR, pairs); | ||||
|  | ||||
| @@ -46,7 +54,7 @@ ParamPackage::ParamPackage(std::initializer_list<DataType::value_type> list) : d | ||||
|  | ||||
| std::string ParamPackage::Serialize() const { | ||||
|     if (data.empty()) | ||||
|         return ""; | ||||
|         return EMPTY_PLACEHOLDER; | ||||
|  | ||||
|     std::string result; | ||||
|  | ||||
| @@ -120,4 +128,12 @@ bool ParamPackage::Has(const std::string& key) const { | ||||
|     return data.find(key) != data.end(); | ||||
| } | ||||
|  | ||||
| void ParamPackage::Erase(const std::string& key) { | ||||
|     data.erase(key); | ||||
| } | ||||
|  | ||||
| void ParamPackage::Clear() { | ||||
|     data.clear(); | ||||
| } | ||||
|  | ||||
| } // namespace Common | ||||
|   | ||||
| @@ -32,6 +32,8 @@ public: | ||||
|     void Set(const std::string& key, int value); | ||||
|     void Set(const std::string& key, float value); | ||||
|     bool Has(const std::string& key) const; | ||||
|     void Erase(const std::string& key); | ||||
|     void Clear(); | ||||
|  | ||||
| private: | ||||
|     DataType data; | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <algorithm> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| #include <QMenu> | ||||
| #include <QMessageBox> | ||||
| #include <QTimer> | ||||
| #include "common/param_package.h" | ||||
| @@ -128,28 +129,63 @@ ConfigureInput::ConfigureInput(QWidget* parent) | ||||
|     analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog}; | ||||
|  | ||||
|     for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { | ||||
|         if (button_map[button_id]) | ||||
|             connect(button_map[button_id], &QPushButton::released, [=]() { | ||||
|                 handleClick( | ||||
|                     button_map[button_id], | ||||
|                     [=](const Common::ParamPackage& params) { buttons_param[button_id] = params; }, | ||||
|                     InputCommon::Polling::DeviceType::Button); | ||||
|             }); | ||||
|         if (!button_map[button_id]) | ||||
|             continue; | ||||
|         button_map[button_id]->setContextMenuPolicy(Qt::CustomContextMenu); | ||||
|         connect(button_map[button_id], &QPushButton::released, [=]() { | ||||
|             handleClick( | ||||
|                 button_map[button_id], | ||||
|                 [=](const Common::ParamPackage& params) { buttons_param[button_id] = params; }, | ||||
|                 InputCommon::Polling::DeviceType::Button); | ||||
|         }); | ||||
|         connect(button_map[button_id], &QPushButton::customContextMenuRequested, | ||||
|                 [=](const QPoint& menu_location) { | ||||
|                     QMenu context_menu; | ||||
|                     context_menu.addAction(tr("Clear"), [&] { | ||||
|                         buttons_param[button_id].Clear(); | ||||
|                         button_map[button_id]->setText(tr("[not set]")); | ||||
|                     }); | ||||
|                     context_menu.addAction(tr("Restore Default"), [&] { | ||||
|                         buttons_param[button_id] = Common::ParamPackage{ | ||||
|                             InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])}; | ||||
|                         button_map[button_id]->setText(ButtonToText(buttons_param[button_id])); | ||||
|                     }); | ||||
|                     context_menu.exec(button_map[button_id]->mapToGlobal(menu_location)); | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) { | ||||
|         for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) { | ||||
|             if (analog_map_buttons[analog_id][sub_button_id] != nullptr) { | ||||
|                 connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::released, | ||||
|                         [=]() { | ||||
|                             handleClick(analog_map_buttons[analog_id][sub_button_id], | ||||
|                                         [=](const Common::ParamPackage& params) { | ||||
|                                             SetAnalogButton(params, analogs_param[analog_id], | ||||
|                                                             analog_sub_buttons[sub_button_id]); | ||||
|                                         }, | ||||
|                                         InputCommon::Polling::DeviceType::Button); | ||||
|             if (!analog_map_buttons[analog_id][sub_button_id]) | ||||
|                 continue; | ||||
|             analog_map_buttons[analog_id][sub_button_id]->setContextMenuPolicy( | ||||
|                 Qt::CustomContextMenu); | ||||
|             connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::released, [=]() { | ||||
|                 handleClick(analog_map_buttons[analog_id][sub_button_id], | ||||
|                             [=](const Common::ParamPackage& params) { | ||||
|                                 SetAnalogButton(params, analogs_param[analog_id], | ||||
|                                                 analog_sub_buttons[sub_button_id]); | ||||
|                             }, | ||||
|                             InputCommon::Polling::DeviceType::Button); | ||||
|             }); | ||||
|             connect(analog_map_buttons[analog_id][sub_button_id], | ||||
|                     &QPushButton::customContextMenuRequested, [=](const QPoint& menu_location) { | ||||
|                         QMenu context_menu; | ||||
|                         context_menu.addAction(tr("Clear"), [&] { | ||||
|                             analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]); | ||||
|                             analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]")); | ||||
|                         }); | ||||
|             } | ||||
|                         context_menu.addAction(tr("Restore Default"), [&] { | ||||
|                             Common::ParamPackage params{InputCommon::GenerateKeyboardParam( | ||||
|                                 Config::default_analogs[analog_id][sub_button_id])}; | ||||
|                             SetAnalogButton(params, analogs_param[analog_id], | ||||
|                                             analog_sub_buttons[sub_button_id]); | ||||
|                             analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText( | ||||
|                                 analogs_param[analog_id], analog_sub_buttons[sub_button_id])); | ||||
|                         }); | ||||
|                         context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal( | ||||
|                             menu_location)); | ||||
|                     }); | ||||
|         } | ||||
|         connect(analog_map_stick[analog_id], &QPushButton::released, [=]() { | ||||
|             QMessageBox::information(this, tr("Information"), | ||||
| @@ -162,6 +198,7 @@ ConfigureInput::ConfigureInput(QWidget* parent) | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     connect(ui->buttonClearAll, &QPushButton::released, [this] { ClearAll(); }); | ||||
|     connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); }); | ||||
|  | ||||
|     timeout_timer->setSingleShot(true); | ||||
| @@ -215,7 +252,21 @@ void ConfigureInput::restoreDefaults() { | ||||
|         } | ||||
|     } | ||||
|     updateButtonLabels(); | ||||
|     applyConfiguration(); | ||||
| } | ||||
|  | ||||
| void ConfigureInput::ClearAll() { | ||||
|     for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { | ||||
|         if (button_map[button_id] && button_map[button_id]->isEnabled()) | ||||
|             buttons_param[button_id].Clear(); | ||||
|     } | ||||
|     for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) { | ||||
|         for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) { | ||||
|             if (analog_map_buttons[analog_id][sub_button_id] && | ||||
|                 analog_map_buttons[analog_id][sub_button_id]->isEnabled()) | ||||
|                 analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]); | ||||
|         } | ||||
|     } | ||||
|     updateButtonLabels(); | ||||
| } | ||||
|  | ||||
| void ConfigureInput::updateButtonLabels() { | ||||
|   | ||||
| @@ -72,6 +72,9 @@ private: | ||||
|     void loadConfiguration(); | ||||
|     /// Restore all buttons to their default values. | ||||
|     void restoreDefaults(); | ||||
|     /// Clear all input configuration | ||||
|     void ClearAll(); | ||||
|  | ||||
|     /// Update UI to reflect current configuration. | ||||
|     void updateButtonLabels(); | ||||
|  | ||||
|   | ||||
| @@ -694,6 +694,34 @@ Capture:</string> | ||||
|        </property> | ||||
|       </spacer> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="buttonClearAll"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||||
|          <horstretch>0</horstretch> | ||||
|          <verstretch>0</verstretch> | ||||
|         </sizepolicy> | ||||
|        </property> | ||||
|        <property name="sizeIncrement"> | ||||
|         <size> | ||||
|          <width>0</width> | ||||
|          <height>0</height> | ||||
|         </size> | ||||
|        </property> | ||||
|        <property name="baseSize"> | ||||
|         <size> | ||||
|          <width>0</width> | ||||
|          <height>0</height> | ||||
|         </size> | ||||
|        </property> | ||||
|        <property name="layoutDirection"> | ||||
|         <enum>Qt::LeftToRight</enum> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Clear All</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="buttonRestoreDefaults"> | ||||
|        <property name="sizePolicy"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 zhupengfei
					zhupengfei