mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	citra-qt: Add base support for hotkey reconfiguration + UI (whole of PR citra-emu/citra#3786)
* Adds a new Hotkeys tab in the Controls group. * Right click to reconfigure. * See the original PR for more details & screenshots.
This commit is contained in:
		
							parent
							
								
									95a57a2fe3
								
							
						
					
					
						commit
						5fa25fcf13
					
				
					 22 changed files with 559 additions and 306 deletions
				
			
		|  | @ -41,6 +41,8 @@ add_executable(citra-qt | ||||||
|     configuration/configure_general.h |     configuration/configure_general.h | ||||||
|     configuration/configure_graphics.cpp |     configuration/configure_graphics.cpp | ||||||
|     configuration/configure_graphics.h |     configuration/configure_graphics.h | ||||||
|  |     configuration/configure_hotkeys.cpp | ||||||
|  |     configuration/configure_hotkeys.h | ||||||
|     configuration/configure_input.cpp |     configuration/configure_input.cpp | ||||||
|     configuration/configure_input.h |     configuration/configure_input.h | ||||||
|     configuration/configure_motion_touch.cpp |     configuration/configure_motion_touch.cpp | ||||||
|  | @ -109,8 +111,10 @@ add_executable(citra-qt | ||||||
|     updater/updater.cpp |     updater/updater.cpp | ||||||
|     updater/updater.h |     updater/updater.h | ||||||
|     updater/updater_p.h |     updater/updater_p.h | ||||||
|     util/clickable_label.h |  | ||||||
|     util/clickable_label.cpp |     util/clickable_label.cpp | ||||||
|  |     util/clickable_label.h | ||||||
|  |     util/sequence_dialog/sequence_dialog.cpp | ||||||
|  |     util/sequence_dialog/sequence_dialog.h | ||||||
|     util/spinbox.cpp |     util/spinbox.cpp | ||||||
|     util/spinbox.h |     util/spinbox.h | ||||||
|     util/util.cpp |     util/util.cpp | ||||||
|  | @ -126,6 +130,7 @@ set(UIS | ||||||
|     configuration/configure_debug.ui |     configuration/configure_debug.ui | ||||||
|     configuration/configure_general.ui |     configuration/configure_general.ui | ||||||
|     configuration/configure_graphics.ui |     configuration/configure_graphics.ui | ||||||
|  |     configuration/configure_hotkeys.ui | ||||||
|     configuration/configure_input.ui |     configuration/configure_input.ui | ||||||
|     configuration/configure_motion_touch.ui |     configuration/configure_motion_touch.ui | ||||||
|     configuration/configure_system.ui |     configuration/configure_system.ui | ||||||
|  | @ -140,7 +145,6 @@ set(UIS | ||||||
|     multiplayer/moderation_dialog.ui |     multiplayer/moderation_dialog.ui | ||||||
|     aboutdialog.ui |     aboutdialog.ui | ||||||
|     cheats.ui |     cheats.ui | ||||||
|     hotkeys.ui |  | ||||||
|     main.ui |     main.ui | ||||||
|     compatdb.ui |     compatdb.ui | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,9 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  | #include <array> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
|  | #include <QKeySequence> | ||||||
| #include <QSettings> | #include <QSettings> | ||||||
| #include "citra_qt/configuration/config.h" | #include "citra_qt/configuration/config.h" | ||||||
| #include "citra_qt/ui_settings.h" | #include "citra_qt/ui_settings.h" | ||||||
|  | @ -318,20 +320,46 @@ void Config::ReadValues() { | ||||||
|     qt_config->endGroup(); |     qt_config->endGroup(); | ||||||
| 
 | 
 | ||||||
|     qt_config->beginGroup("Shortcuts"); |     qt_config->beginGroup("Shortcuts"); | ||||||
|     QStringList groups = qt_config->childGroups(); |     const std::array<UISettings::Shortcut, 14> default_hotkeys{ | ||||||
|     for (auto group : groups) { |         {{"Load File", "Main Window", | ||||||
|         qt_config->beginGroup(group); |           UISettings::ContextualShortcut(QKeySequence(QKeySequence::Open).toString(), | ||||||
|  |                                          Qt::WindowShortcut)}, | ||||||
|  |          {"Exit Citra", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("Ctrl+Q", Qt::WindowShortcut)}, | ||||||
|  |          {"Continue/Pause Emulation", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("F4", Qt::WindowShortcut)}, | ||||||
|  |          {"Stop Emulation", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("F5", Qt::WindowShortcut)}, | ||||||
|  |          {"Restart Emulation", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("F6", Qt::WindowShortcut)}, | ||||||
|  |          {"Swap Screens", "Main Window", UISettings::ContextualShortcut("F9", Qt::WindowShortcut)}, | ||||||
|  |          {"Toggle Screen Layout", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("F10", Qt::WindowShortcut)}, | ||||||
|  |          {"Toggle Filter Bar", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("Ctrl+F", Qt::WindowShortcut)}, | ||||||
|  |          {"Toggle Status Bar", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("Ctrl+S", Qt::WindowShortcut)}, | ||||||
|  |          {"Fullscreen", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut(QKeySequence(QKeySequence::FullScreen).toString(), | ||||||
|  |                                          Qt::WindowShortcut)}, | ||||||
|  |          {"Exit Fullscreen", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("Escape", Qt::WindowShortcut)}, | ||||||
|  |          {"Toggle Speed Limit", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("Ctrl+Z", Qt::ApplicationShortcut)}, | ||||||
|  |          {"Increase Speed Limit", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("+", Qt::ApplicationShortcut)}, | ||||||
|  |          {"Decrease Speed Limit", "Main Window", | ||||||
|  |           UISettings::ContextualShortcut("-", Qt::ApplicationShortcut)}}}; | ||||||
| 
 | 
 | ||||||
|         QStringList hotkeys = qt_config->childGroups(); |     for (int i = 0; i < default_hotkeys.size(); i++) { | ||||||
|         for (auto hotkey : hotkeys) { |         qt_config->beginGroup(default_hotkeys[i].group); | ||||||
|             qt_config->beginGroup(hotkey); |         qt_config->beginGroup(default_hotkeys[i].name); | ||||||
|             UISettings::values.shortcuts.emplace_back(UISettings::Shortcut( |         UISettings::values.shortcuts.push_back( | ||||||
|                 group + "/" + hotkey, |             {default_hotkeys[i].name, default_hotkeys[i].group, | ||||||
|                 UISettings::ContextualShortcut(ReadSetting("KeySeq").toString(), |              UISettings::ContextualShortcut( | ||||||
|                                                ReadSetting("Context").toInt()))); |                  qt_config->value("KeySeq", default_hotkeys[i].shortcut.first).toString(), | ||||||
|  |                  qt_config->value("Context", default_hotkeys[i].shortcut.second).toInt())}); | ||||||
|         qt_config->endGroup(); |         qt_config->endGroup(); | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         qt_config->endGroup(); |         qt_config->endGroup(); | ||||||
|     } |     } | ||||||
|     qt_config->endGroup(); |     qt_config->endGroup(); | ||||||
|  | @ -564,8 +592,12 @@ void Config::SaveValues() { | ||||||
| 
 | 
 | ||||||
|     qt_config->beginGroup("Shortcuts"); |     qt_config->beginGroup("Shortcuts"); | ||||||
|     for (auto shortcut : UISettings::values.shortcuts) { |     for (auto shortcut : UISettings::values.shortcuts) { | ||||||
|         WriteSetting(shortcut.first + "/KeySeq", shortcut.second.first); |         qt_config->beginGroup(shortcut.group); | ||||||
|         WriteSetting(shortcut.first + "/Context", shortcut.second.second); |         qt_config->beginGroup(shortcut.name); | ||||||
|  |         WriteSetting("KeySeq", shortcut.shortcut.first); | ||||||
|  |         WriteSetting("Context", shortcut.shortcut.second); | ||||||
|  |         qt_config->endGroup(); | ||||||
|  |         qt_config->endGroup(); | ||||||
|     } |     } | ||||||
|     qt_config->endGroup(); |     qt_config->endGroup(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,6 +38,11 @@ | ||||||
|          <string>Input</string> |          <string>Input</string> | ||||||
|         </attribute> |         </attribute> | ||||||
|        </widget> |        </widget> | ||||||
|  |        <widget class="ConfigureHotkeys" name="hotkeysTab"> | ||||||
|  |         <attribute name="title"> | ||||||
|  |          <string>Hotkeys</string> | ||||||
|  |         </attribute> | ||||||
|  |        </widget> | ||||||
|        <widget class="ConfigureGraphics" name="graphicsTab"> |        <widget class="ConfigureGraphics" name="graphicsTab"> | ||||||
|         <attribute name="title"> |         <attribute name="title"> | ||||||
|          <string>Graphics</string> |          <string>Graphics</string> | ||||||
|  | @ -118,6 +123,12 @@ | ||||||
|    <header>configuration/configure_input.h</header> |    <header>configuration/configure_input.h</header> | ||||||
|    <container>1</container> |    <container>1</container> | ||||||
|   </customwidget> |   </customwidget> | ||||||
|  |   <customwidget> | ||||||
|  |    <class>ConfigureHotkeys</class> | ||||||
|  |    <extends>QWidget</extends> | ||||||
|  |    <header>configuration/configure_hotkeys.h</header> | ||||||
|  |    <container>1</container> | ||||||
|  |   </customwidget> | ||||||
|   <customwidget> |   <customwidget> | ||||||
|    <class>ConfigureGraphics</class> |    <class>ConfigureGraphics</class> | ||||||
|    <extends>QWidget</extends> |    <extends>QWidget</extends> | ||||||
|  |  | ||||||
|  | @ -13,15 +13,25 @@ | ||||||
| ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry) | ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry) | ||||||
|     : QDialog(parent), ui(new Ui::ConfigureDialog) { |     : QDialog(parent), ui(new Ui::ConfigureDialog) { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
|     ui->generalTab->PopulateHotkeyList(registry); |     ui->hotkeysTab->Populate(registry); | ||||||
|  | 
 | ||||||
|     this->PopulateSelectionList(); |     this->PopulateSelectionList(); | ||||||
|     connect(ui->uiTab, &ConfigureUi::languageChanged, this, &ConfigureDialog::onLanguageChanged); |     connect(ui->uiTab, &ConfigureUi::languageChanged, this, &ConfigureDialog::onLanguageChanged); | ||||||
|     connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, |     connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, | ||||||
|             &ConfigureDialog::UpdateVisibleTabs); |             &ConfigureDialog::UpdateVisibleTabs); | ||||||
| 
 |  | ||||||
|     adjustSize(); |     adjustSize(); | ||||||
| 
 |  | ||||||
|     ui->selectorList->setCurrentRow(0); |     ui->selectorList->setCurrentRow(0); | ||||||
|  | 
 | ||||||
|  |     connect(ui->inputTab, &ConfigureInput::InputKeysChanged, ui->hotkeysTab, | ||||||
|  |             &ConfigureHotkeys::OnInputKeysChanged); | ||||||
|  |     connect(ui->hotkeysTab, &ConfigureHotkeys::HotkeysChanged, ui->inputTab, | ||||||
|  |             &ConfigureInput::OnHotkeysChanged); | ||||||
|  |     connect(ui->hotkeysTab, &ConfigureHotkeys::HotkeysChanged, this, | ||||||
|  |             [this]() { emit UpdateHotkeys(); }); | ||||||
|  | 
 | ||||||
|  |     // Synchronise lists upon initialisation
 | ||||||
|  |     ui->inputTab->EmitInputKeysChanged(); | ||||||
|  |     ui->hotkeysTab->EmitHotkeysChanged(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ConfigureDialog::~ConfigureDialog() = default; | ConfigureDialog::~ConfigureDialog() = default; | ||||||
|  | @ -38,11 +48,12 @@ void ConfigureDialog::setConfiguration() { | ||||||
|     ui->uiTab->setConfiguration(); |     ui->uiTab->setConfiguration(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureDialog::applyConfiguration() { | void ConfigureDialog::applyConfiguration(HotkeyRegistry& registry) { | ||||||
|     ui->generalTab->applyConfiguration(); |     ui->generalTab->applyConfiguration(); | ||||||
|     ui->systemTab->applyConfiguration(); |     ui->systemTab->applyConfiguration(); | ||||||
|     ui->inputTab->applyConfiguration(); |     ui->inputTab->applyConfiguration(); | ||||||
|     ui->inputTab->ApplyProfile(); |     ui->inputTab->ApplyProfile(); | ||||||
|  |     ui->hotkeysTab->applyConfiguration(registry); | ||||||
|     ui->graphicsTab->applyConfiguration(); |     ui->graphicsTab->applyConfiguration(); | ||||||
|     ui->audioTab->applyConfiguration(); |     ui->audioTab->applyConfiguration(); | ||||||
|     ui->cameraTab->applyConfiguration(); |     ui->cameraTab->applyConfiguration(); | ||||||
|  | @ -61,7 +72,7 @@ void ConfigureDialog::PopulateSelectionList() { | ||||||
|           {QT_TR_NOOP("General"), QT_TR_NOOP("Web"), QT_TR_NOOP("Debug"), QT_TR_NOOP("UI")}}, |           {QT_TR_NOOP("General"), QT_TR_NOOP("Web"), QT_TR_NOOP("Debug"), QT_TR_NOOP("UI")}}, | ||||||
|          {tr("System"), {QT_TR_NOOP("System"), QT_TR_NOOP("Audio"), QT_TR_NOOP("Camera")}}, |          {tr("System"), {QT_TR_NOOP("System"), QT_TR_NOOP("Audio"), QT_TR_NOOP("Camera")}}, | ||||||
|          {tr("Graphics"), {QT_TR_NOOP("Graphics")}}, |          {tr("Graphics"), {QT_TR_NOOP("Graphics")}}, | ||||||
|          {tr("Controls"), {QT_TR_NOOP("Input")}}}}; |          {tr("Controls"), {QT_TR_NOOP("Input"), QT_TR_NOOP("Hotkeys")}}}}; | ||||||
| 
 | 
 | ||||||
|     for (const auto& entry : items) { |     for (const auto& entry : items) { | ||||||
|         auto* item = new QListWidgetItem(entry.first); |         auto* item = new QListWidgetItem(entry.first); | ||||||
|  | @ -91,6 +102,7 @@ void ConfigureDialog::retranslateUi() { | ||||||
|     ui->generalTab->retranslateUi(); |     ui->generalTab->retranslateUi(); | ||||||
|     ui->systemTab->retranslateUi(); |     ui->systemTab->retranslateUi(); | ||||||
|     ui->inputTab->retranslateUi(); |     ui->inputTab->retranslateUi(); | ||||||
|  |     ui->hotkeysTab->retranslateUi(); | ||||||
|     ui->graphicsTab->retranslateUi(); |     ui->graphicsTab->retranslateUi(); | ||||||
|     ui->audioTab->retranslateUi(); |     ui->audioTab->retranslateUi(); | ||||||
|     ui->cameraTab->retranslateUi(); |     ui->cameraTab->retranslateUi(); | ||||||
|  | @ -105,9 +117,11 @@ void ConfigureDialog::UpdateVisibleTabs() { | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     const QHash<QString, QWidget*> widgets = { |     const QHash<QString, QWidget*> widgets = { | ||||||
|         {"General", ui->generalTab},   {"System", ui->systemTab}, {"Input", ui->inputTab}, |         {tr("General"), ui->generalTab},   {tr("System"), ui->systemTab}, | ||||||
|         {"Graphics", ui->graphicsTab}, {"Audio", ui->audioTab},   {"Camera", ui->cameraTab}, |         {tr("Input"), ui->inputTab},       {tr("Hotkeys"), ui->hotkeysTab}, | ||||||
|         {"Debug", ui->debugTab},       {"Web", ui->webTab},       {"UI", ui->uiTab}}; |         {tr("Graphics"), ui->graphicsTab}, {tr("Audio"), ui->audioTab}, | ||||||
|  |         {tr("Camera"), ui->cameraTab},     {tr("Debug"), ui->debugTab}, | ||||||
|  |         {tr("Web"), ui->webTab},           {tr("UI"), ui->uiTab}}; | ||||||
| 
 | 
 | ||||||
|     ui->tabWidget->clear(); |     ui->tabWidget->clear(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,15 +20,16 @@ public: | ||||||
|     explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); |     explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); | ||||||
|     ~ConfigureDialog() override; |     ~ConfigureDialog() override; | ||||||
| 
 | 
 | ||||||
|     void applyConfiguration(); |  | ||||||
|     void UpdateVisibleTabs(); |     void UpdateVisibleTabs(); | ||||||
|     void PopulateSelectionList(); |     void PopulateSelectionList(); | ||||||
|  |     void applyConfiguration(HotkeyRegistry& registry); | ||||||
| 
 | 
 | ||||||
| private slots: | private slots: | ||||||
|     void onLanguageChanged(const QString& locale); |     void onLanguageChanged(const QString& locale); | ||||||
| 
 | 
 | ||||||
| signals: | signals: | ||||||
|     void languageChanged(const QString& locale); |     void languageChanged(const QString& locale); | ||||||
|  |     void UpdateHotkeys(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void setConfiguration(); |     void setConfiguration(); | ||||||
|  |  | ||||||
|  | @ -32,10 +32,6 @@ void ConfigureGeneral::setConfiguration() { | ||||||
|     ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1); |     ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) { |  | ||||||
|     ui->hotkeysDialog->Populate(registry); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ConfigureGeneral::ResetDefaults() { | void ConfigureGeneral::ResetDefaults() { | ||||||
|     QMessageBox::StandardButton answer = QMessageBox::question( |     QMessageBox::StandardButton answer = QMessageBox::question( | ||||||
|         this, tr("Citra"), |         this, tr("Citra"), | ||||||
|  | @ -60,5 +56,4 @@ void ConfigureGeneral::applyConfiguration() { | ||||||
| 
 | 
 | ||||||
| void ConfigureGeneral::retranslateUi() { | void ConfigureGeneral::retranslateUi() { | ||||||
|     ui->retranslateUi(this); |     ui->retranslateUi(this); | ||||||
|     ui->hotkeysDialog->retranslateUi(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ public: | ||||||
|     explicit ConfigureGeneral(QWidget* parent = nullptr); |     explicit ConfigureGeneral(QWidget* parent = nullptr); | ||||||
|     ~ConfigureGeneral() override; |     ~ConfigureGeneral() override; | ||||||
| 
 | 
 | ||||||
|     void PopulateHotkeyList(const HotkeyRegistry& registry); |  | ||||||
|     void ResetDefaults(); |     void ResetDefaults(); | ||||||
|     void applyConfiguration(); |     void applyConfiguration(); | ||||||
|     void retranslateUi(); |     void retranslateUi(); | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
|     <x>0</x> |     <x>0</x> | ||||||
|     <y>0</y> |     <y>0</y> | ||||||
|     <width>345</width> |     <width>345</width> | ||||||
|     <height>504</height> |     <height>357</height> | ||||||
|    </rect> |    </rect> | ||||||
|   </property> |   </property> | ||||||
|   <property name="windowTitle"> |   <property name="windowTitle"> | ||||||
|  | @ -21,9 +21,7 @@ | ||||||
|        <property name="title"> |        <property name="title"> | ||||||
|         <string>General</string> |         <string>General</string> | ||||||
|        </property> |        </property> | ||||||
|        <layout class="QHBoxLayout" name="horizontalLayout_3"> |        <layout class="QVBoxLayout" name="verticalLayout_5"> | ||||||
|         <item> |  | ||||||
|          <layout class="QVBoxLayout" name="verticalLayout_2"> |  | ||||||
|         <item> |         <item> | ||||||
|          <widget class="QCheckBox" name="toggle_check_exit"> |          <widget class="QCheckBox" name="toggle_check_exit"> | ||||||
|           <property name="text"> |           <property name="text"> | ||||||
|  | @ -32,8 +30,6 @@ | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|        </layout> |        </layout> | ||||||
|         </item> |  | ||||||
|        </layout> |  | ||||||
|       </widget> |       </widget> | ||||||
|      </item> |      </item> | ||||||
|      <item> |      <item> | ||||||
|  | @ -41,9 +37,7 @@ | ||||||
|        <property name="title"> |        <property name="title"> | ||||||
|         <string>Updates</string> |         <string>Updates</string> | ||||||
|        </property> |        </property> | ||||||
|        <layout class="QHBoxLayout" name="horizontalLayout_update"> |        <layout class="QVBoxLayout" name="verticalLayout_4"> | ||||||
|         <item> |  | ||||||
|          <layout class="QVBoxLayout" name="verticalLayout_update"> |  | ||||||
|         <item> |         <item> | ||||||
|          <widget class="QCheckBox" name="toggle_update_check"> |          <widget class="QCheckBox" name="toggle_update_check"> | ||||||
|           <property name="text"> |           <property name="text"> | ||||||
|  | @ -59,8 +53,6 @@ | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|        </layout> |        </layout> | ||||||
|         </item> |  | ||||||
|        </layout> |  | ||||||
|       </widget> |       </widget> | ||||||
|      </item> |      </item> | ||||||
|      <item> |      <item> | ||||||
|  | @ -68,19 +60,15 @@ | ||||||
|        <property name="title"> |        <property name="title"> | ||||||
|         <string>Emulation</string> |         <string>Emulation</string> | ||||||
|        </property> |        </property> | ||||||
|        <layout class="QHBoxLayout" name="horizontalLayout_5"> |        <layout class="QGridLayout" name="gridLayout"> | ||||||
|         <item> |         <item row="0" column="0"> | ||||||
|          <layout class="QVBoxLayout" name="verticalLayout_6"> |  | ||||||
|           <item> |  | ||||||
|            <layout class="QHBoxLayout" name="horizontalLayout_6"> |  | ||||||
|             <item> |  | ||||||
|          <widget class="QLabel" name="label"> |          <widget class="QLabel" name="label"> | ||||||
|           <property name="text"> |           <property name="text"> | ||||||
|            <string>Region:</string> |            <string>Region:</string> | ||||||
|           </property> |           </property> | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|             <item> |         <item row="0" column="1"> | ||||||
|          <widget class="QComboBox" name="region_combobox"> |          <widget class="QComboBox" name="region_combobox"> | ||||||
|           <item> |           <item> | ||||||
|            <property name="text"> |            <property name="text"> | ||||||
|  | @ -125,26 +113,6 @@ | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|        </layout> |        </layout> | ||||||
|           </item> |  | ||||||
|          </layout> |  | ||||||
|         </item> |  | ||||||
|        </layout> |  | ||||||
|       </widget> |  | ||||||
|      </item> |  | ||||||
|      <item> |  | ||||||
|       <widget class="QGroupBox" name="groupBox_3"> |  | ||||||
|        <property name="title"> |  | ||||||
|         <string>Hotkeys</string> |  | ||||||
|        </property> |  | ||||||
|        <layout class="QHBoxLayout" name="horizontalLayout_4"> |  | ||||||
|         <item> |  | ||||||
|          <layout class="QVBoxLayout" name="verticalLayout_4"> |  | ||||||
|           <item> |  | ||||||
|            <widget class="GHotkeysDialog" name="hotkeysDialog" native="true"/> |  | ||||||
|           </item> |  | ||||||
|          </layout> |  | ||||||
|         </item> |  | ||||||
|        </layout> |  | ||||||
|       </widget> |       </widget> | ||||||
|      </item> |      </item> | ||||||
|      <item alignment="Qt::AlignRight"> |      <item alignment="Qt::AlignRight"> | ||||||
|  | @ -158,14 +126,6 @@ | ||||||
|    </item> |    </item> | ||||||
|   </layout> |   </layout> | ||||||
|  </widget> |  </widget> | ||||||
|  <customwidgets> |  | ||||||
|   <customwidget> |  | ||||||
|    <class>GHotkeysDialog</class> |  | ||||||
|    <extends>QWidget</extends> |  | ||||||
|    <header>hotkeys.h</header> |  | ||||||
|    <container>1</container> |  | ||||||
|   </customwidget> |  | ||||||
|  </customwidgets> |  | ||||||
|  <resources/> |  <resources/> | ||||||
|  <connections/> |  <connections/> | ||||||
| </ui> | </ui> | ||||||
|  |  | ||||||
							
								
								
									
										130
									
								
								src/citra_qt/configuration/configure_hotkeys.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/citra_qt/configuration/configure_hotkeys.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | ||||||
|  | // Copyright 2017 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <QMessageBox> | ||||||
|  | #include "citra_qt/configuration/configure_hotkeys.h" | ||||||
|  | #include "citra_qt/hotkeys.h" | ||||||
|  | #include "citra_qt/util/sequence_dialog/sequence_dialog.h" | ||||||
|  | #include "core/settings.h" | ||||||
|  | #include "ui_configure_hotkeys.h" | ||||||
|  | 
 | ||||||
|  | ConfigureHotkeys::ConfigureHotkeys(QWidget* parent) | ||||||
|  |     : QWidget(parent), ui(std::make_unique<Ui::ConfigureHotkeys>()) { | ||||||
|  |     ui->setupUi(this); | ||||||
|  |     setFocusPolicy(Qt::ClickFocus); | ||||||
|  | 
 | ||||||
|  |     model = new QStandardItemModel(this); | ||||||
|  |     model->setColumnCount(3); | ||||||
|  |     model->setHorizontalHeaderLabels({tr("Action"), tr("Hotkey"), tr("Context")}); | ||||||
|  | 
 | ||||||
|  |     ui->hotkey_list->setSelectionMode(QTreeView::SingleSelection); | ||||||
|  |     connect(ui->hotkey_list, &QTreeView::doubleClicked, this, &ConfigureHotkeys::Configure); | ||||||
|  |     ui->hotkey_list->setModel(model); | ||||||
|  | 
 | ||||||
|  |     // TODO(Kloen): Make context configurable as well (hiding the column for now)
 | ||||||
|  |     ui->hotkey_list->hideColumn(2); | ||||||
|  | 
 | ||||||
|  |     ui->hotkey_list->setColumnWidth(0, 200); | ||||||
|  |     ui->hotkey_list->resizeColumnToContents(1); | ||||||
|  |     ui->hotkey_list->setEditTriggers(QTreeView::NoEditTriggers); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ConfigureHotkeys::~ConfigureHotkeys() {} | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::EmitHotkeysChanged() { | ||||||
|  |     emit HotkeysChanged(GetUsedKeyList()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QList<QKeySequence> ConfigureHotkeys::GetUsedKeyList() { | ||||||
|  |     QList<QKeySequence> list; | ||||||
|  |     for (int r = 0; r < model->rowCount(); r++) { | ||||||
|  |         QStandardItem* parent = model->item(r, 0); | ||||||
|  |         for (int r2 = 0; r2 < parent->rowCount(); r2++) { | ||||||
|  |             QStandardItem* keyseq = parent->child(r2, 1); | ||||||
|  |             list << QKeySequence::fromString(keyseq->text(), QKeySequence::NativeText); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) { | ||||||
|  |     for (const auto& group : registry.hotkey_groups) { | ||||||
|  |         QStandardItem* parent_item = new QStandardItem(group.first); | ||||||
|  |         parent_item->setEditable(false); | ||||||
|  |         for (const auto& hotkey : group.second) { | ||||||
|  |             QStandardItem* action = new QStandardItem(hotkey.first); | ||||||
|  |             QStandardItem* keyseq = | ||||||
|  |                 new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText)); | ||||||
|  |             action->setEditable(false); | ||||||
|  |             keyseq->setEditable(false); | ||||||
|  |             parent_item->appendRow({action, keyseq}); | ||||||
|  |         } | ||||||
|  |         model->appendRow(parent_item); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ui->hotkey_list->expandAll(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::OnInputKeysChanged(QList<QKeySequence> new_key_list) { | ||||||
|  |     input_keys_list = new_key_list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::Configure(QModelIndex index) { | ||||||
|  |     if (index.parent() == QModelIndex()) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     index = index.sibling(index.row(), 1); | ||||||
|  |     auto* model = ui->hotkey_list->model(); | ||||||
|  |     auto previous_key = model->data(index); | ||||||
|  | 
 | ||||||
|  |     auto* hotkey_dialog = new SequenceDialog; | ||||||
|  |     int return_code = hotkey_dialog->exec(); | ||||||
|  | 
 | ||||||
|  |     auto key_sequence = hotkey_dialog->GetSequence(); | ||||||
|  | 
 | ||||||
|  |     if (return_code == QDialog::Rejected || key_sequence.isEmpty()) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     if (IsUsedKey(key_sequence) && | ||||||
|  |         key_sequence != QKeySequence(previous_key.toString(), QKeySequence::NativeText)) { | ||||||
|  |         model->setData(index, previous_key); | ||||||
|  |         QMessageBox::critical(this, tr("Error in inputted key"), | ||||||
|  |                               tr("You're using a key that's already bound.")); | ||||||
|  |     } else { | ||||||
|  |         model->setData(index, key_sequence.toString(QKeySequence::NativeText)); | ||||||
|  |         EmitHotkeysChanged(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) { | ||||||
|  |     return input_keys_list.contains(key_sequence) || GetUsedKeyList().contains(key_sequence); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) { | ||||||
|  |     for (int key_id = 0; key_id < model->rowCount(); key_id++) { | ||||||
|  |         QStandardItem* parent = model->item(key_id, 0); | ||||||
|  |         for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) { | ||||||
|  |             QStandardItem* action = parent->child(key_column_id, 0); | ||||||
|  |             QStandardItem* keyseq = parent->child(key_column_id, 1); | ||||||
|  |             for (auto key_iterator = registry.hotkey_groups.begin(); | ||||||
|  |                  key_iterator != registry.hotkey_groups.end(); ++key_iterator) { | ||||||
|  |                 if (key_iterator->first == parent->text()) { | ||||||
|  |                     for (auto it2 = key_iterator->second.begin(); it2 != key_iterator->second.end(); | ||||||
|  |                          ++it2) { | ||||||
|  |                         if (it2->first == action->text()) { | ||||||
|  |                             it2->second.keyseq = QKeySequence(keyseq->text()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     registry.SaveHotkeys(); | ||||||
|  |     Settings::Apply(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureHotkeys::retranslateUi() { | ||||||
|  |     ui->retranslateUi(this); | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								src/citra_qt/configuration/configure_hotkeys.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/citra_qt/configuration/configure_hotkeys.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | ||||||
|  | // Copyright 2017 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <QStandardItemModel> | ||||||
|  | #include <QWidget> | ||||||
|  | #include "common/param_package.h" | ||||||
|  | #include "core/settings.h" | ||||||
|  | 
 | ||||||
|  | namespace Ui { | ||||||
|  | class ConfigureHotkeys; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class HotkeyRegistry; | ||||||
|  | 
 | ||||||
|  | class ConfigureHotkeys : public QWidget { | ||||||
|  |     Q_OBJECT | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     explicit ConfigureHotkeys(QWidget* parent = nullptr); | ||||||
|  |     ~ConfigureHotkeys(); | ||||||
|  | 
 | ||||||
|  |     void applyConfiguration(HotkeyRegistry& registry); | ||||||
|  |     void retranslateUi(); | ||||||
|  | 
 | ||||||
|  |     void EmitHotkeysChanged(); | ||||||
|  | 
 | ||||||
|  |     void Populate(const HotkeyRegistry& registry); | ||||||
|  | 
 | ||||||
|  | public slots: | ||||||
|  |     void OnInputKeysChanged(QList<QKeySequence> new_key_list); | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |     void HotkeysChanged(QList<QKeySequence> new_key_list); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void Configure(QModelIndex index); | ||||||
|  |     bool IsUsedKey(QKeySequence key_sequence); | ||||||
|  |     QList<QKeySequence> GetUsedKeyList(); | ||||||
|  | 
 | ||||||
|  |     std::unique_ptr<Ui::ConfigureHotkeys> ui; | ||||||
|  | 
 | ||||||
|  |     QList<QKeySequence> input_keys_list; | ||||||
|  |     QStandardItemModel* model; | ||||||
|  | }; | ||||||
							
								
								
									
										35
									
								
								src/citra_qt/configuration/configure_hotkeys.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/citra_qt/configuration/configure_hotkeys.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>ConfigureHotkeys</class> | ||||||
|  |  <widget class="QWidget" name="ConfigureHotkeys"> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>363</width> | ||||||
|  |     <height>388</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Hotkey Settings</string> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  |    <item> | ||||||
|  |     <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||||
|  |      <item> | ||||||
|  |       <widget class="QLabel" name="label_2"> | ||||||
|  |        <property name="text"> | ||||||
|  |         <string>Double-click on a binding to change it.</string> | ||||||
|  |        </property> | ||||||
|  |       </widget> | ||||||
|  |      </item> | ||||||
|  |      <item> | ||||||
|  |       <widget class="QTreeView" name="hotkey_list"/> | ||||||
|  |      </item> | ||||||
|  |     </layout> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <resources/> | ||||||
|  |  <connections/> | ||||||
|  | </ui> | ||||||
|  | @ -276,6 +276,30 @@ void ConfigureInput::ApplyProfile() { | ||||||
|     Settings::values.current_input_profile_index = ui->profile->currentIndex(); |     Settings::values.current_input_profile_index = ui->profile->currentIndex(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ConfigureInput::EmitInputKeysChanged() { | ||||||
|  |     emit InputKeysChanged(GetUsedKeyboardKeys()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ConfigureInput::OnHotkeysChanged(QList<QKeySequence> new_key_list) { | ||||||
|  |     hotkey_list = new_key_list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QList<QKeySequence> ConfigureInput::GetUsedKeyboardKeys() { | ||||||
|  |     QList<QKeySequence> list; | ||||||
|  |     for (int button = 0; button < Settings::NativeButton::NumButtons; button++) { | ||||||
|  |         auto button_param = buttons_param[button]; | ||||||
|  | 
 | ||||||
|  |         if (button_param.Get("engine", "") == "keyboard") { | ||||||
|  |             list << QKeySequence(button_param.Get("code", 0)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // TODO(adityaruplaha): Add home button to list when we finally emulate it
 | ||||||
|  |     // Button ID of home button is 14: Reffered from citra_qt/configuration/config.cpp
 | ||||||
|  |     list.removeOne(list.indexOf(QKeySequence(buttons_param[14].Get("code", 0)))); | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ConfigureInput::loadConfiguration() { | void ConfigureInput::loadConfiguration() { | ||||||
|     std::transform(Settings::values.current_input_profile.buttons.begin(), |     std::transform(Settings::values.current_input_profile.buttons.begin(), | ||||||
|                    Settings::values.current_input_profile.buttons.end(), buttons_param.begin(), |                    Settings::values.current_input_profile.buttons.end(), buttons_param.begin(), | ||||||
|  | @ -332,11 +356,14 @@ void ConfigureInput::updateButtonLabels() { | ||||||
|         } |         } | ||||||
|         analog_map_stick[analog_id]->setText(tr("Set Analog Stick")); |         analog_map_stick[analog_id]->setText(tr("Set Analog Stick")); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     EmitInputKeysChanged(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureInput::handleClick(QPushButton* button, | void ConfigureInput::handleClick(QPushButton* button, | ||||||
|                                  std::function<void(const Common::ParamPackage&)> new_input_setter, |                                  std::function<void(const Common::ParamPackage&)> new_input_setter, | ||||||
|                                  InputCommon::Polling::DeviceType type) { |                                  InputCommon::Polling::DeviceType type) { | ||||||
|  |     previous_key_code = QKeySequence(button->text())[0]; | ||||||
|     button->setText(tr("[press key]")); |     button->setText(tr("[press key]")); | ||||||
|     button->setFocus(); |     button->setFocus(); | ||||||
| 
 | 
 | ||||||
|  | @ -378,16 +405,26 @@ void ConfigureInput::keyPressEvent(QKeyEvent* event) { | ||||||
|     if (!input_setter || !event) |     if (!input_setter || !event) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     if (event->key() != Qt::Key_Escape) { |     if (event->key() != Qt::Key_Escape && event->key() != previous_key_code) { | ||||||
|         if (want_keyboard_keys) { |         if (want_keyboard_keys) { | ||||||
|  |             // Check if key is already bound
 | ||||||
|  |             if (hotkey_list.contains(QKeySequence(event->key())) || | ||||||
|  |                 GetUsedKeyboardKeys().contains(QKeySequence(event->key()))) { | ||||||
|  |                 setPollingResult({}, true); | ||||||
|  |                 QMessageBox::critical(this, tr("Error!"), | ||||||
|  |                                       tr("You're using a key that's already bound.")); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|             setPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())}, |             setPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())}, | ||||||
|                              false); |                              false); | ||||||
|         } else { |         } else { | ||||||
|             // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop polling
 |             // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop
 | ||||||
|  |             // polling
 | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     setPollingResult({}, true); |     setPollingResult({}, true); | ||||||
|  |     previous_key_code = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureInput::retranslateUi() { | void ConfigureInput::retranslateUi() { | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include <string> | #include <string> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <QKeyEvent> | #include <QKeyEvent> | ||||||
|  | #include <QKeySequence> | ||||||
| #include <QWidget> | #include <QWidget> | ||||||
| #include "common/param_package.h" | #include "common/param_package.h" | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
|  | @ -38,6 +39,13 @@ public: | ||||||
| 
 | 
 | ||||||
|     /// Load configuration settings.
 |     /// Load configuration settings.
 | ||||||
|     void loadConfiguration(); |     void loadConfiguration(); | ||||||
|  |     void EmitInputKeysChanged(); | ||||||
|  | 
 | ||||||
|  | public slots: | ||||||
|  |     void OnHotkeysChanged(QList<QKeySequence> new_key_list); | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |     void InputKeysChanged(QList<QKeySequence> new_key_list); | ||||||
| 
 | 
 | ||||||
|     // Save the current input profile index
 |     // Save the current input profile index
 | ||||||
|     void ApplyProfile(); |     void ApplyProfile(); | ||||||
|  | @ -72,10 +80,16 @@ private: | ||||||
| 
 | 
 | ||||||
|     std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; |     std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; | ||||||
| 
 | 
 | ||||||
|  |     /// Keys currently registered as hotkeys
 | ||||||
|  |     QList<QKeySequence> hotkey_list; | ||||||
|  | 
 | ||||||
|     /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
 |     /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
 | ||||||
|     /// keyboard events are ignored.
 |     /// keyboard events are ignored.
 | ||||||
|     bool want_keyboard_keys = false; |     bool want_keyboard_keys = false; | ||||||
| 
 | 
 | ||||||
|  |     /// Generates list of all used keys
 | ||||||
|  |     QList<QKeySequence> GetUsedKeyboardKeys(); | ||||||
|  | 
 | ||||||
|     /// Restore all buttons to their default values.
 |     /// Restore all buttons to their default values.
 | ||||||
|     void restoreDefaults(); |     void restoreDefaults(); | ||||||
|     /// Clear all input configuration
 |     /// Clear all input configuration
 | ||||||
|  | @ -89,6 +103,9 @@ private: | ||||||
|                      std::function<void(const Common::ParamPackage&)> new_input_setter, |                      std::function<void(const Common::ParamPackage&)> new_input_setter, | ||||||
|                      InputCommon::Polling::DeviceType type); |                      InputCommon::Polling::DeviceType type); | ||||||
| 
 | 
 | ||||||
|  |     /// The key code of the previous state of the key being currently bound.
 | ||||||
|  |     int previous_key_code; | ||||||
|  | 
 | ||||||
|     /// Finish polling and configure input using the input_setter
 |     /// Finish polling and configure input using the input_setter
 | ||||||
|     void setPollingResult(const Common::ParamPackage& params, bool abort); |     void setPollingResult(const Common::ParamPackage& params, bool abort); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <map> |  | ||||||
| #include <QKeySequence> | #include <QKeySequence> | ||||||
| #include <QShortcut> | #include <QShortcut> | ||||||
| #include <QtGlobal> | #include <QtGlobal> | ||||||
|  | @ -12,47 +11,30 @@ | ||||||
| HotkeyRegistry::HotkeyRegistry() = default; | HotkeyRegistry::HotkeyRegistry() = default; | ||||||
| HotkeyRegistry::~HotkeyRegistry() = default; | HotkeyRegistry::~HotkeyRegistry() = default; | ||||||
| 
 | 
 | ||||||
| void HotkeyRegistry::LoadHotkeys() { |  | ||||||
|     // Make sure NOT to use a reference here because it would become invalid once we call
 |  | ||||||
|     // beginGroup()
 |  | ||||||
|     for (auto shortcut : UISettings::values.shortcuts) { |  | ||||||
|         const QStringList cat = shortcut.first.split('/'); |  | ||||||
|         Q_ASSERT(cat.size() >= 2); |  | ||||||
| 
 |  | ||||||
|         // RegisterHotkey assigns default keybindings, so use old values as default parameters
 |  | ||||||
|         Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; |  | ||||||
|         if (!shortcut.second.first.isEmpty()) { |  | ||||||
|             hk.keyseq = QKeySequence::fromString(shortcut.second.first); |  | ||||||
|             hk.context = static_cast<Qt::ShortcutContext>(shortcut.second.second); |  | ||||||
|         } |  | ||||||
|         if (hk.shortcut) |  | ||||||
|             hk.shortcut->setKey(hk.keyseq); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HotkeyRegistry::SaveHotkeys() { | void HotkeyRegistry::SaveHotkeys() { | ||||||
|     UISettings::values.shortcuts.clear(); |     UISettings::values.shortcuts.clear(); | ||||||
|     for (const auto& group : hotkey_groups) { |     for (const auto& group : hotkey_groups) { | ||||||
|         for (const auto& hotkey : group.second) { |         for (const auto& hotkey : group.second) { | ||||||
|             UISettings::values.shortcuts.emplace_back( |             UISettings::values.shortcuts.push_back( | ||||||
|                 UISettings::Shortcut(group.first + '/' + hotkey.first, |                 {hotkey.first, group.first, | ||||||
|                  UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), |                  UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), | ||||||
|                                                                     hotkey.second.context))); |                                                 hotkey.second.context)}); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HotkeyRegistry::RegisterHotkey(const QString& group, const QString& action, | void HotkeyRegistry::LoadHotkeys() { | ||||||
|                                     const QKeySequence& default_keyseq, |     // Make sure NOT to use a reference here because it would become invalid once we call
 | ||||||
|                                     Qt::ShortcutContext default_context) { |     // beginGroup()
 | ||||||
|     auto& hotkey_group = hotkey_groups[group]; |     for (auto shortcut : UISettings::values.shortcuts) { | ||||||
|     if (hotkey_group.find(action) != hotkey_group.end()) { |         Hotkey& hk = hotkey_groups[shortcut.group][shortcut.name]; | ||||||
|         return; |         if (!shortcut.shortcut.first.isEmpty()) { | ||||||
|  |             hk.keyseq = QKeySequence::fromString(shortcut.shortcut.first, QKeySequence::NativeText); | ||||||
|  |             hk.context = (Qt::ShortcutContext)shortcut.shortcut.second; | ||||||
|  |         } | ||||||
|  |         if (hk.shortcut) | ||||||
|  |             hk.shortcut->setKey(hk.keyseq); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     auto& hotkey_action = hotkey_groups[group][action]; |  | ||||||
|     hotkey_action.keyseq = default_keyseq; |  | ||||||
|     hotkey_action.context = default_context; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) { | QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) { | ||||||
|  | @ -64,28 +46,13 @@ QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action | ||||||
|     return hk.shortcut; |     return hk.shortcut; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { | QKeySequence HotkeyRegistry::GetKeySequence(const QString& group, const QString& action) { | ||||||
|     ui.setupUi(this); |     Hotkey& hk = hotkey_groups[group][action]; | ||||||
|  |     return hk.keyseq; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GHotkeysDialog::Populate(const HotkeyRegistry& registry) { | Qt::ShortcutContext HotkeyRegistry::GetShortcutContext(const QString& group, | ||||||
|     for (const auto& group : registry.hotkey_groups) { |                                                        const QString& action) { | ||||||
|         QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); |     Hotkey& hk = hotkey_groups[group][action]; | ||||||
|         for (const auto& hotkey : group.second) { |     return hk.context; | ||||||
|             QStringList columns; |  | ||||||
|             columns << hotkey.first << hotkey.second.keyseq.toString(); |  | ||||||
|             QTreeWidgetItem* item = new QTreeWidgetItem(columns); |  | ||||||
|             toplevel_item->addChild(item); |  | ||||||
|         } |  | ||||||
|         ui.treeWidget->addTopLevelItem(toplevel_item); |  | ||||||
|     } |  | ||||||
|     // TODO: Make context configurable as well (hiding the column for now)
 |  | ||||||
|     ui.treeWidget->setColumnCount(2); |  | ||||||
| 
 |  | ||||||
|     ui.treeWidget->resizeColumnToContents(0); |  | ||||||
|     ui.treeWidget->resizeColumnToContents(1); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void GHotkeysDialog::retranslateUi() { |  | ||||||
|     ui.retranslateUi(this); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <map> | #include <map> | ||||||
| #include "ui_hotkeys.h" |  | ||||||
| 
 | 
 | ||||||
| class QDialog; | class QDialog; | ||||||
| class QKeySequence; | class QKeySequence; | ||||||
|  | @ -14,7 +13,7 @@ class QShortcut; | ||||||
| 
 | 
 | ||||||
| class HotkeyRegistry final { | class HotkeyRegistry final { | ||||||
| public: | public: | ||||||
|     friend class GHotkeysDialog; |     friend class ConfigureHotkeys; | ||||||
| 
 | 
 | ||||||
|     explicit HotkeyRegistry(); |     explicit HotkeyRegistry(); | ||||||
|     ~HotkeyRegistry(); |     ~HotkeyRegistry(); | ||||||
|  | @ -49,22 +48,26 @@ public: | ||||||
|     QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); |     QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Register a hotkey. |      * Returns a QKeySequence object who signal can be connected to QAction->SetShortcut. | ||||||
|      * |      * | ||||||
|      * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") |      * @param group  General group this hotkey belongs to (e.g. "Main Window", "Debugger"). | ||||||
|      * @param action Name of the action (e.g. "Start Emulation", "Load Image") |      * @param action Name of the action (e.g. "Start Emulation", "Load Image"). | ||||||
|      * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the |  | ||||||
|      *                       settings file before |  | ||||||
|      * @param default_context Default context to assign if the hotkey wasn't present in the settings |  | ||||||
|      *                        file before |  | ||||||
|      * @warning Both the group and action strings will be displayed in the hotkey settings dialog |  | ||||||
|      */ |      */ | ||||||
|     void RegisterHotkey(const QString& group, const QString& action, |     QKeySequence GetKeySequence(const QString& group, const QString& action); | ||||||
|                         const QKeySequence& default_keyseq = {}, | 
 | ||||||
|                         Qt::ShortcutContext default_context = Qt::WindowShortcut); |     /**
 | ||||||
|  |      * Returns a Qt::ShortcutContext object who can be connected to other | ||||||
|  |      * QAction->SetShortcutContext. | ||||||
|  |      * | ||||||
|  |      * @param group  General group this shortcutcontext belongs to (e.g. "Main Window", "Debugger"). | ||||||
|  |      * @param action Name of the action (e.g. "Start Emulation", "Load Image"). | ||||||
|  |      */ | ||||||
|  |     Qt::ShortcutContext GetShortcutContext(const QString& group, const QString& action); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     struct Hotkey { |     struct Hotkey { | ||||||
|  |         Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} | ||||||
|  | 
 | ||||||
|         QKeySequence keyseq; |         QKeySequence keyseq; | ||||||
|         QShortcut* shortcut = nullptr; |         QShortcut* shortcut = nullptr; | ||||||
|         Qt::ShortcutContext context = Qt::WindowShortcut; |         Qt::ShortcutContext context = Qt::WindowShortcut; | ||||||
|  | @ -75,16 +78,3 @@ private: | ||||||
| 
 | 
 | ||||||
|     HotkeyGroupMap hotkey_groups; |     HotkeyGroupMap hotkey_groups; | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| class GHotkeysDialog : public QWidget { |  | ||||||
|     Q_OBJECT |  | ||||||
| 
 |  | ||||||
| public: |  | ||||||
|     explicit GHotkeysDialog(QWidget* parent = nullptr); |  | ||||||
|     void retranslateUi(); |  | ||||||
| 
 |  | ||||||
|     void Populate(const HotkeyRegistry& registry); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     Ui::hotkeys ui; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  | @ -1,46 +0,0 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <ui version="4.0"> |  | ||||||
|  <class>hotkeys</class> |  | ||||||
|  <widget class="QWidget" name="hotkeys"> |  | ||||||
|   <property name="geometry"> |  | ||||||
|    <rect> |  | ||||||
|     <x>0</x> |  | ||||||
|     <y>0</y> |  | ||||||
|     <width>363</width> |  | ||||||
|     <height>388</height> |  | ||||||
|    </rect> |  | ||||||
|   </property> |  | ||||||
|   <property name="windowTitle"> |  | ||||||
|    <string>Hotkey Settings</string> |  | ||||||
|   </property> |  | ||||||
|   <layout class="QVBoxLayout" name="verticalLayout"> |  | ||||||
|    <item> |  | ||||||
|     <widget class="QTreeWidget" name="treeWidget"> |  | ||||||
|      <property name="selectionBehavior"> |  | ||||||
|       <enum>QAbstractItemView::SelectItems</enum> |  | ||||||
|      </property> |  | ||||||
|      <property name="headerHidden"> |  | ||||||
|       <bool>false</bool> |  | ||||||
|      </property> |  | ||||||
|      <column> |  | ||||||
|       <property name="text"> |  | ||||||
|        <string>Action</string> |  | ||||||
|       </property> |  | ||||||
|      </column> |  | ||||||
|      <column> |  | ||||||
|       <property name="text"> |  | ||||||
|        <string>Hotkey</string> |  | ||||||
|       </property> |  | ||||||
|      </column> |  | ||||||
|      <column> |  | ||||||
|       <property name="text"> |  | ||||||
|        <string>Context</string> |  | ||||||
|       </property> |  | ||||||
|      </column> |  | ||||||
|     </widget> |  | ||||||
|    </item> |  | ||||||
|   </layout> |  | ||||||
|  </widget> |  | ||||||
|  <resources/> |  | ||||||
|  <connections/> |  | ||||||
| </ui> |  | ||||||
|  | @ -344,40 +344,35 @@ void GMainWindow::InitializeRecentFileMenuActions() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::InitializeHotkeys() { | void GMainWindow::InitializeHotkeys() { | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Start Emulation"); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4)); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Restart", QKeySequence(Qt::Key_F5)); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Swap Screens", QKeySequence(Qt::Key_F9)); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Toggle Screen Layout", |  | ||||||
|                                    QKeySequence(Qt::Key_F10)); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Increase Speed Limit", QKeySequence("+"), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Decrease Speed Limit", QKeySequence("-"), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Toggle Frame Advancing", QKeySequence("CTRL+A"), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Advance Frame", QKeySequence(Qt::Key_Backslash), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Load Amiibo", QKeySequence(Qt::Key_F2), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Remove Amiibo", QKeySequence(Qt::Key_F3), |  | ||||||
|                                    Qt::ApplicationShortcut); |  | ||||||
|     hotkey_registry.RegisterHotkey("Main Window", "Capture Screenshot", QKeySequence(tr("CTRL+P"))); |  | ||||||
| 
 |  | ||||||
|     hotkey_registry.LoadHotkeys(); |     hotkey_registry.LoadHotkeys(); | ||||||
| 
 | 
 | ||||||
|  |     ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Load File")); | ||||||
|  |     ui.action_Load_File->setShortcutContext( | ||||||
|  |         hotkey_registry.GetShortcutContext("Main Window", "Load File")); | ||||||
|  | 
 | ||||||
|  |     ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Exit Citra")); | ||||||
|  |     ui.action_Exit->setShortcutContext( | ||||||
|  |         hotkey_registry.GetShortcutContext("Main Window", "Exit Citra")); | ||||||
|  | 
 | ||||||
|  |     ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Stop Emulation")); | ||||||
|  |     ui.action_Stop->setShortcutContext( | ||||||
|  |         hotkey_registry.GetShortcutContext("Main Window", "Stop Emulation")); | ||||||
|  | 
 | ||||||
|  |     ui.action_Show_Filter_Bar->setShortcut( | ||||||
|  |         hotkey_registry.GetKeySequence("Main Window", "Toggle Filter Bar")); | ||||||
|  |     ui.action_Show_Filter_Bar->setShortcutContext( | ||||||
|  |         hotkey_registry.GetShortcutContext("Main Window", "Toggle Filter Bar")); | ||||||
|  | 
 | ||||||
|  |     ui.action_Show_Status_Bar->setShortcut( | ||||||
|  |         hotkey_registry.GetKeySequence("Main Window", "Toggle Status Bar")); | ||||||
|  |     ui.action_Show_Status_Bar->setShortcutContext( | ||||||
|  |         hotkey_registry.GetShortcutContext("Main Window", "Toggle Status Bar")); | ||||||
|  | 
 | ||||||
|     connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated, |     connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated, | ||||||
|             this, &GMainWindow::OnMenuLoadFile); |             this, &GMainWindow::OnMenuLoadFile); | ||||||
|     connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this), | 
 | ||||||
|             &QShortcut::activated, this, &GMainWindow::OnStartGame); |     connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause Emulation", this), | ||||||
|     connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated, |             &QShortcut::activated, this, [&] { | ||||||
|             this, [&] { |  | ||||||
|                 if (emulation_running) { |                 if (emulation_running) { | ||||||
|                     if (emu_thread->IsRunning()) { |                     if (emu_thread->IsRunning()) { | ||||||
|                         OnPauseGame(); |                         OnPauseGame(); | ||||||
|  | @ -386,8 +381,8 @@ void GMainWindow::InitializeHotkeys() { | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|     connect(hotkey_registry.GetHotkey("Main Window", "Restart", this), &QShortcut::activated, this, |     connect(hotkey_registry.GetHotkey("Main Window", "Restart Emulation", this), | ||||||
|             [this] { |             &QShortcut::activated, this, [this] { | ||||||
|                 if (!Core::System::GetInstance().IsPoweredOn()) |                 if (!Core::System::GetInstance().IsPoweredOn()) | ||||||
|                     return; |                     return; | ||||||
|                 BootGame(QString(game_path)); |                 BootGame(QString(game_path)); | ||||||
|  | @ -546,7 +541,6 @@ void GMainWindow::ConnectMenuEvents() { | ||||||
|             &GMainWindow::ToggleWindowMode); |             &GMainWindow::ToggleWindowMode); | ||||||
|     connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this, |     connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this, | ||||||
|             &GMainWindow::OnDisplayTitleBars); |             &GMainWindow::OnDisplayTitleBars); | ||||||
|     ui.action_Show_Filter_Bar->setShortcut(tr("CTRL+F")); |  | ||||||
|     connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); |     connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); | ||||||
|     connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); |     connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); | ||||||
| 
 | 
 | ||||||
|  | @ -1325,13 +1319,15 @@ void GMainWindow::OnConfigure() { | ||||||
|     ConfigureDialog configureDialog(this, hotkey_registry); |     ConfigureDialog configureDialog(this, hotkey_registry); | ||||||
|     connect(&configureDialog, &ConfigureDialog::languageChanged, this, |     connect(&configureDialog, &ConfigureDialog::languageChanged, this, | ||||||
|             &GMainWindow::OnLanguageChanged); |             &GMainWindow::OnLanguageChanged); | ||||||
|  |     connect(&configureDialog, &ConfigureDialog::UpdateHotkeys, this, | ||||||
|  |             [this]() { InitializeHotkeys(); }); | ||||||
|     auto old_theme = UISettings::values.theme; |     auto old_theme = UISettings::values.theme; | ||||||
|     const int old_input_profile_index = Settings::values.current_input_profile_index; |     const int old_input_profile_index = Settings::values.current_input_profile_index; | ||||||
|     const auto old_input_profiles = Settings::values.input_profiles; |     const auto old_input_profiles = Settings::values.input_profiles; | ||||||
|     const bool old_discord_presence = UISettings::values.enable_discord_presence; |     const bool old_discord_presence = UISettings::values.enable_discord_presence; | ||||||
|     auto result = configureDialog.exec(); |     auto result = configureDialog.exec(); | ||||||
|     if (result == QDialog::Accepted) { |     if (result == QDialog::Accepted) { | ||||||
|         configureDialog.applyConfiguration(); |         configureDialog.applyConfiguration(hotkey_registry); | ||||||
|         if (UISettings::values.theme != old_theme) |         if (UISettings::values.theme != old_theme) | ||||||
|             UpdateUITheme(); |             UpdateUITheme(); | ||||||
|         if (UISettings::values.enable_discord_presence != old_discord_presence) |         if (UISettings::values.enable_discord_presence != old_discord_presence) | ||||||
|  |  | ||||||
|  | @ -96,7 +96,6 @@ private: | ||||||
|     void InitializeWidgets(); |     void InitializeWidgets(); | ||||||
|     void InitializeDebugWidgets(); |     void InitializeDebugWidgets(); | ||||||
|     void InitializeRecentFileMenuActions(); |     void InitializeRecentFileMenuActions(); | ||||||
|     void InitializeHotkeys(); |  | ||||||
| 
 | 
 | ||||||
|     void SetDefaultUIGeometry(); |     void SetDefaultUIGeometry(); | ||||||
|     void SyncMenuUISettings(); |     void SyncMenuUISettings(); | ||||||
|  | @ -171,6 +170,7 @@ private slots: | ||||||
|     void OnOpenCitraFolder(); |     void OnOpenCitraFolder(); | ||||||
|     void OnToggleFilterBar(); |     void OnToggleFilterBar(); | ||||||
|     void OnDisplayTitleBars(bool); |     void OnDisplayTitleBars(bool); | ||||||
|  |     void InitializeHotkeys(); | ||||||
|     void ToggleFullscreen(); |     void ToggleFullscreen(); | ||||||
|     void ChangeScreenLayout(); |     void ChangeScreenLayout(); | ||||||
|     void ToggleScreenLayout(); |     void ToggleScreenLayout(); | ||||||
|  |  | ||||||
|  | @ -14,5 +14,4 @@ const Themes themes{{ | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
| Values values = {}; | Values values = {}; | ||||||
| 
 |  | ||||||
| } // namespace UISettings
 | } // namespace UISettings
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,12 @@ | ||||||
| namespace UISettings { | namespace UISettings { | ||||||
| 
 | 
 | ||||||
| using ContextualShortcut = std::pair<QString, int>; | using ContextualShortcut = std::pair<QString, int>; | ||||||
| using Shortcut = std::pair<QString, ContextualShortcut>; | 
 | ||||||
|  | struct Shortcut { | ||||||
|  |     QString name; | ||||||
|  |     QString group; | ||||||
|  |     ContextualShortcut shortcut; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| using Themes = std::array<std::pair<const char*, const char*>, 4>; | using Themes = std::array<std::pair<const char*, const char*>, 4>; | ||||||
| extern const Themes themes; | extern const Themes themes; | ||||||
|  |  | ||||||
							
								
								
									
										35
									
								
								src/citra_qt/util/sequence_dialog/sequence_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/citra_qt/util/sequence_dialog/sequence_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | // Copyright 2018 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <QDialogButtonBox> | ||||||
|  | #include <QVBoxLayout> | ||||||
|  | #include "citra_qt/util/sequence_dialog/sequence_dialog.h" | ||||||
|  | 
 | ||||||
|  | SequenceDialog::SequenceDialog(QWidget* parent) : QDialog(parent) { | ||||||
|  |     setWindowTitle(tr("Enter a hotkey")); | ||||||
|  |     auto* layout = new QVBoxLayout(this); | ||||||
|  |     key_sequence = new QKeySequenceEdit; | ||||||
|  |     layout->addWidget(key_sequence); | ||||||
|  |     auto* buttons = | ||||||
|  |         new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal); | ||||||
|  |     buttons->setCenterButtons(true); | ||||||
|  |     layout->addWidget(buttons); | ||||||
|  |     connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); | ||||||
|  |     connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); | ||||||
|  |     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SequenceDialog::~SequenceDialog() = default; | ||||||
|  | 
 | ||||||
|  | QKeySequence SequenceDialog::GetSequence() { | ||||||
|  |     return QKeySequence(key_sequence->keySequence()[0]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool SequenceDialog::focusNextPrevChild(bool next) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SequenceDialog::closeEvent(QCloseEvent*) { | ||||||
|  |     reject(); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								src/citra_qt/util/sequence_dialog/sequence_dialog.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/citra_qt/util/sequence_dialog/sequence_dialog.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | // Copyright 2018 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <QDialog> | ||||||
|  | #include <QKeySequenceEdit> | ||||||
|  | 
 | ||||||
|  | class SequenceDialog : public QDialog { | ||||||
|  |     Q_OBJECT | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     explicit SequenceDialog(QWidget* parent = nullptr); | ||||||
|  |     ~SequenceDialog(); | ||||||
|  | 
 | ||||||
|  |     QKeySequence GetSequence(); | ||||||
|  |     void closeEvent(QCloseEvent*) override; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     QKeySequenceEdit* key_sequence; | ||||||
|  |     bool focusNextPrevChild(bool next) override; | ||||||
|  | }; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue