Browse Source
Merge pull request #1780 from DarkLordZach/controller-profiles
Merge pull request #1780 from DarkLordZach/controller-profiles
configure_input: Add Controller Setup Profiles and simplify input UInce_cpp
committed by
GitHub
12 changed files with 401 additions and 66 deletions
-
3src/yuzu/CMakeLists.txt
-
12src/yuzu/configuration/config.cpp
-
1src/yuzu/configuration/config.h
-
52src/yuzu/configuration/configure.ui
-
60src/yuzu/configuration/configure_input.cpp
-
8src/yuzu/configuration/configure_input.h
-
48src/yuzu/configuration/configure_input.ui
-
1src/yuzu/configuration/configure_input_player.cpp
-
142src/yuzu/configuration/configure_input_simple.cpp
-
40src/yuzu/configuration/configure_input_simple.h
-
97src/yuzu/configuration/configure_input_simple.ui
-
3src/yuzu/ui_settings.h
@ -0,0 +1,142 @@ |
|||||
|
// Copyright 2016 Citra Emulator Project
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <array>
|
||||
|
#include <cstring>
|
||||
|
#include <functional>
|
||||
|
#include <tuple>
|
||||
|
|
||||
|
#include <QDialog>
|
||||
|
|
||||
|
#include "ui_configure_input_simple.h"
|
||||
|
#include "yuzu/configuration/configure_input.h"
|
||||
|
#include "yuzu/configuration/configure_input_player.h"
|
||||
|
#include "yuzu/configuration/configure_input_simple.h"
|
||||
|
#include "yuzu/ui_settings.h"
|
||||
|
|
||||
|
namespace { |
||||
|
|
||||
|
template <typename Dialog, typename... Args> |
||||
|
void CallConfigureDialog(ConfigureInputSimple* caller, Args&&... args) { |
||||
|
caller->applyConfiguration(); |
||||
|
Dialog dialog(caller, std::forward<Args>(args)...); |
||||
|
|
||||
|
const auto res = dialog.exec(); |
||||
|
if (res == QDialog::Accepted) { |
||||
|
dialog.applyConfiguration(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// OnProfileSelect functions should (when applicable):
|
||||
|
// - Set controller types
|
||||
|
// - Set controller enabled
|
||||
|
// - Set docked mode
|
||||
|
// - Set advanced controller config/enabled (i.e. debug, kbd, mouse, touch)
|
||||
|
//
|
||||
|
// OnProfileSelect function should NOT however:
|
||||
|
// - Reset any button mappings
|
||||
|
// - Open any dialogs
|
||||
|
// - Block in any way
|
||||
|
|
||||
|
constexpr std::size_t HANDHELD_INDEX = 8; |
||||
|
|
||||
|
void HandheldOnProfileSelect() { |
||||
|
Settings::values.players[HANDHELD_INDEX].connected = true; |
||||
|
Settings::values.players[HANDHELD_INDEX].type = Settings::ControllerType::DualJoycon; |
||||
|
|
||||
|
for (std::size_t player = 0; player < HANDHELD_INDEX; ++player) { |
||||
|
Settings::values.players[player].connected = false; |
||||
|
} |
||||
|
|
||||
|
Settings::values.use_docked_mode = false; |
||||
|
Settings::values.keyboard_enabled = false; |
||||
|
Settings::values.mouse_enabled = false; |
||||
|
Settings::values.debug_pad_enabled = false; |
||||
|
Settings::values.touchscreen.enabled = true; |
||||
|
} |
||||
|
|
||||
|
void DualJoyconsDockedOnProfileSelect() { |
||||
|
Settings::values.players[0].connected = true; |
||||
|
Settings::values.players[0].type = Settings::ControllerType::DualJoycon; |
||||
|
|
||||
|
for (std::size_t player = 1; player <= HANDHELD_INDEX; ++player) { |
||||
|
Settings::values.players[player].connected = false; |
||||
|
} |
||||
|
|
||||
|
Settings::values.use_docked_mode = true; |
||||
|
Settings::values.keyboard_enabled = false; |
||||
|
Settings::values.mouse_enabled = false; |
||||
|
Settings::values.debug_pad_enabled = false; |
||||
|
Settings::values.touchscreen.enabled = false; |
||||
|
} |
||||
|
|
||||
|
// Name, OnProfileSelect (called when selected in drop down), OnConfigure (called when configure
|
||||
|
// is clicked)
|
||||
|
using InputProfile = |
||||
|
std::tuple<QString, std::function<void()>, std::function<void(ConfigureInputSimple*)>>; |
||||
|
|
||||
|
const std::array<InputProfile, 3> INPUT_PROFILES{{ |
||||
|
{ConfigureInputSimple::tr("Single Player - Handheld - Undocked"), HandheldOnProfileSelect, |
||||
|
[](ConfigureInputSimple* caller) { |
||||
|
CallConfigureDialog<ConfigureInputPlayer>(caller, HANDHELD_INDEX, false); |
||||
|
}}, |
||||
|
{ConfigureInputSimple::tr("Single Player - Dual Joycons - Docked"), |
||||
|
DualJoyconsDockedOnProfileSelect, |
||||
|
[](ConfigureInputSimple* caller) { |
||||
|
CallConfigureDialog<ConfigureInputPlayer>(caller, 1, false); |
||||
|
}}, |
||||
|
{ConfigureInputSimple::tr("Custom"), [] {}, CallConfigureDialog<ConfigureInput>}, |
||||
|
}}; |
||||
|
|
||||
|
} // namespace
|
||||
|
|
||||
|
void ApplyInputProfileConfiguration(int profile_index) { |
||||
|
std::get<1>( |
||||
|
INPUT_PROFILES.at(std::min(profile_index, static_cast<int>(INPUT_PROFILES.size() - 1))))(); |
||||
|
} |
||||
|
|
||||
|
ConfigureInputSimple::ConfigureInputSimple(QWidget* parent) |
||||
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputSimple>()) { |
||||
|
ui->setupUi(this); |
||||
|
|
||||
|
for (const auto& profile : INPUT_PROFILES) { |
||||
|
ui->profile_combobox->addItem(std::get<0>(profile), std::get<0>(profile)); |
||||
|
} |
||||
|
|
||||
|
connect(ui->profile_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, |
||||
|
&ConfigureInputSimple::OnSelectProfile); |
||||
|
connect(ui->profile_configure, &QPushButton::pressed, this, &ConfigureInputSimple::OnConfigure); |
||||
|
|
||||
|
this->loadConfiguration(); |
||||
|
} |
||||
|
|
||||
|
ConfigureInputSimple::~ConfigureInputSimple() = default; |
||||
|
|
||||
|
void ConfigureInputSimple::applyConfiguration() { |
||||
|
auto index = ui->profile_combobox->currentIndex(); |
||||
|
// Make the stored index for "Custom" very large so that if new profiles are added it
|
||||
|
// doesn't change.
|
||||
|
if (index >= static_cast<int>(INPUT_PROFILES.size() - 1)) |
||||
|
index = std::numeric_limits<int>::max(); |
||||
|
|
||||
|
UISettings::values.profile_index = index; |
||||
|
} |
||||
|
|
||||
|
void ConfigureInputSimple::loadConfiguration() { |
||||
|
const auto index = UISettings::values.profile_index; |
||||
|
if (index >= static_cast<int>(INPUT_PROFILES.size()) || index < 0) |
||||
|
ui->profile_combobox->setCurrentIndex(static_cast<int>(INPUT_PROFILES.size() - 1)); |
||||
|
else |
||||
|
ui->profile_combobox->setCurrentIndex(index); |
||||
|
} |
||||
|
|
||||
|
void ConfigureInputSimple::OnSelectProfile(int index) { |
||||
|
const auto old_docked = Settings::values.use_docked_mode; |
||||
|
ApplyInputProfileConfiguration(index); |
||||
|
OnDockedModeChanged(old_docked, Settings::values.use_docked_mode); |
||||
|
} |
||||
|
|
||||
|
void ConfigureInputSimple::OnConfigure() { |
||||
|
std::get<2>(INPUT_PROFILES.at(ui->profile_combobox->currentIndex()))(this); |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
// Copyright 2016 Citra Emulator Project |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <memory> |
||||
|
|
||||
|
#include <QWidget> |
||||
|
|
||||
|
class QPushButton; |
||||
|
class QString; |
||||
|
class QTimer; |
||||
|
|
||||
|
namespace Ui { |
||||
|
class ConfigureInputSimple; |
||||
|
} |
||||
|
|
||||
|
// Used by configuration loader to apply a profile if the input is invalid. |
||||
|
void ApplyInputProfileConfiguration(int profile_index); |
||||
|
|
||||
|
class ConfigureInputSimple : public QWidget { |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
explicit ConfigureInputSimple(QWidget* parent = nullptr); |
||||
|
~ConfigureInputSimple() override; |
||||
|
|
||||
|
/// Save all button configurations to settings file |
||||
|
void applyConfiguration(); |
||||
|
|
||||
|
private: |
||||
|
/// Load configuration settings. |
||||
|
void loadConfiguration(); |
||||
|
|
||||
|
void OnSelectProfile(int index); |
||||
|
void OnConfigure(); |
||||
|
|
||||
|
std::unique_ptr<Ui::ConfigureInputSimple> ui; |
||||
|
}; |
||||
@ -0,0 +1,97 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<ui version="4.0"> |
||||
|
<class>ConfigureInputSimple</class> |
||||
|
<widget class="QWidget" name="ConfigureInputSimple"> |
||||
|
<property name="geometry"> |
||||
|
<rect> |
||||
|
<x>0</x> |
||||
|
<y>0</y> |
||||
|
<width>473</width> |
||||
|
<height>685</height> |
||||
|
</rect> |
||||
|
</property> |
||||
|
<property name="windowTitle"> |
||||
|
<string>ConfigureInputSimple</string> |
||||
|
</property> |
||||
|
<layout class="QVBoxLayout" name="verticalLayout_5"> |
||||
|
<item> |
||||
|
<layout class="QVBoxLayout" name="verticalLayout"> |
||||
|
<item> |
||||
|
<widget class="QGroupBox" name="gridGroupBox"> |
||||
|
<property name="title"> |
||||
|
<string>Profile</string> |
||||
|
</property> |
||||
|
<layout class="QGridLayout" name="gridLayout"> |
||||
|
<item row="1" column="2"> |
||||
|
<widget class="QPushButton" name="profile_configure"> |
||||
|
<property name="text"> |
||||
|
<string>Configure</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="0"> |
||||
|
<spacer name="horizontalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>40</width> |
||||
|
<height>20</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
<item row="1" column="3"> |
||||
|
<spacer name="horizontalSpacer_2"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>40</width> |
||||
|
<height>20</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
<item row="1" column="1"> |
||||
|
<widget class="QComboBox" name="profile_combobox"> |
||||
|
<property name="minimumSize"> |
||||
|
<size> |
||||
|
<width>250</width> |
||||
|
<height>0</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="0" column="1" colspan="2"> |
||||
|
<widget class="QLabel" name="label"> |
||||
|
<property name="text"> |
||||
|
<string>Choose a controller configuration:</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
<item> |
||||
|
<spacer name="verticalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Vertical</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>20</width> |
||||
|
<height>40</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
<resources/> |
||||
|
<connections/> |
||||
|
</ui> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue