Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #9468 from iwubcode/wiimote_controllers_widget
DolphinQt: Move wiimote controller ui logic to its own widget
  • Loading branch information
leoetlino committed Jan 27, 2021
2 parents fb09acd + f3b6c97 commit 920dd81
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 312 deletions.
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/CMakeLists.txt
Expand Up @@ -192,6 +192,8 @@ add_executable(dolphin-emu
Config/ToolTipControls/ToolTipWidget.h
Config/VerifyWidget.cpp
Config/VerifyWidget.h
Config/WiimoteControllersWidget.cpp
Config/WiimoteControllersWidget.h
Debugger/BreakpointWidget.cpp
Debugger/BreakpointWidget.h
Debugger/CodeViewWidget.cpp
Expand Down
294 changes: 6 additions & 288 deletions Source/Core/DolphinQt/Config/ControllersWindow.cpp
Expand Up @@ -26,15 +26,12 @@
#include "Core/Core.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/IOS/IOS.h"
#include "Core/IOS/USB/Bluetooth/BTReal.h"

#include "DolphinQt/Config/CommonControllersWidget.h"
#include "DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/Config/WiimoteControllersWidget.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -67,7 +64,7 @@ ControllersWindow::ControllersWindow(QWidget* parent) : QDialog(parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

CreateGamecubeLayout();
CreateWiimoteLayout();
m_wiimote_controllers = new WiimoteControllersWidget(this);
m_common = new CommonControllersWidget(this);
CreateMainLayout();
LoadSettings();
Expand Down Expand Up @@ -102,115 +99,13 @@ void ControllersWindow::CreateGamecubeLayout()
m_gc_box->setLayout(m_gc_layout);
}

static int GetRadioButtonIndicatorWidth()
{
const QStyle* style = QApplication::style();
QStyleOptionButton opt;

// TODO: why does the macOS style act different? Is it because of the magic with
// Cocoa widgets it does behind the scenes?
if (style->objectName() == QStringLiteral("macintosh"))
return style->subElementRect(QStyle::SE_RadioButtonIndicator, &opt).width();

return style->subElementRect(QStyle::SE_RadioButtonContents, &opt).left();
}

static int GetLayoutHorizontalSpacing(const QGridLayout* layout)
{
// TODO: shouldn't layout->horizontalSpacing() do all this? Why does it return -1?
int hspacing = layout->horizontalSpacing();
if (hspacing >= 0)
return hspacing;

// According to docs, this is the fallback if horizontalSpacing() isn't set.
auto style = layout->parentWidget()->style();
hspacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
if (hspacing >= 0)
return hspacing;

// Docs claim this is deprecated, but on macOS with Qt 5.8 this is the only one that actually
// works.
float pixel_ratio = QGuiApplication::primaryScreen()->devicePixelRatio();
#ifdef __APPLE__
// TODO is this still required?
hspacing = pixel_ratio * style->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
if (hspacing >= 0)
return hspacing;
#endif

// Ripped from qtbase/src/widgets/styles/qcommonstyle.cpp
return pixel_ratio * 6;
}

void ControllersWindow::CreateWiimoteLayout()
{
m_wiimote_layout = new QGridLayout();
m_wiimote_box = new QGroupBox(tr("Wii Remotes"));
m_wiimote_box->setLayout(m_wiimote_layout);

m_wiimote_passthrough = new QRadioButton(tr("Passthrough a Bluetooth adapter"));
m_wiimote_sync = new QPushButton(tr("Sync"));
m_wiimote_reset = new QPushButton(tr("Reset"));
m_wiimote_refresh = new QPushButton(tr("Refresh"));
m_wiimote_pt_labels[0] = new QLabel(tr("Sync real Wii Remotes and pair them"));
m_wiimote_pt_labels[1] = new QLabel(tr("Reset all saved Wii Remote pairings"));
m_wiimote_emu = new QRadioButton(tr("Emulate the Wii's Bluetooth adapter"));
m_wiimote_continuous_scanning = new QCheckBox(tr("Continuous Scanning"));
m_wiimote_real_balance_board = new QCheckBox(tr("Real Balance Board"));
m_wiimote_speaker_data = new QCheckBox(tr("Enable Speaker Data"));
m_wiimote_ciface = new QCheckBox(tr("Connect Wii Remotes for Emulated Controllers"));

m_wiimote_layout->setVerticalSpacing(7);
m_wiimote_layout->setColumnMinimumWidth(0, GetRadioButtonIndicatorWidth() -
GetLayoutHorizontalSpacing(m_wiimote_layout));
m_wiimote_layout->setColumnStretch(2, 1);

// Passthrough BT
m_wiimote_layout->addWidget(m_wiimote_passthrough, m_wiimote_layout->rowCount(), 0, 1, -1);

int sync_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(m_wiimote_pt_labels[0], sync_row, 1, 1, 2);
m_wiimote_layout->addWidget(m_wiimote_sync, sync_row, 3);

int reset_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(m_wiimote_pt_labels[1], reset_row, 1, 1, 2);
m_wiimote_layout->addWidget(m_wiimote_reset, reset_row, 3);

// Emulated BT
m_wiimote_layout->addWidget(m_wiimote_emu, m_wiimote_layout->rowCount(), 0, 1, -1);

for (size_t i = 0; i < m_wiimote_groups.size(); i++)
{
auto* wm_label = m_wiimote_labels[i] = new QLabel(tr("Wii Remote %1").arg(i + 1));
auto* wm_box = m_wiimote_boxes[i] = new QComboBox();
auto* wm_button = m_wiimote_buttons[i] = new QPushButton(tr("Configure"));

for (const auto& item : {tr("None"), tr("Emulated Wii Remote"), tr("Real Wii Remote")})
wm_box->addItem(item);

int wm_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(wm_label, wm_row, 1);
m_wiimote_layout->addWidget(wm_box, wm_row, 2);
m_wiimote_layout->addWidget(wm_button, wm_row, 3);
}

m_wiimote_layout->addWidget(m_wiimote_real_balance_board, m_wiimote_layout->rowCount(), 1, 1, -1);
m_wiimote_layout->addWidget(m_wiimote_speaker_data, m_wiimote_layout->rowCount(), 1, 1, -1);

m_wiimote_layout->addWidget(m_wiimote_ciface, m_wiimote_layout->rowCount(), 0, 1, -1);

int continuous_scanning_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(m_wiimote_continuous_scanning, continuous_scanning_row, 0, 1, 3);
m_wiimote_layout->addWidget(m_wiimote_refresh, continuous_scanning_row, 3);
}

void ControllersWindow::CreateMainLayout()
{
auto* layout = new QVBoxLayout();
m_button_box = new QDialogButtonBox(QDialogButtonBox::Close);

layout->addWidget(m_gc_box);
layout->addWidget(m_wiimote_box);
layout->addWidget(m_wiimote_controllers);
layout->addWidget(m_common);
layout->addStretch();
layout->addWidget(m_button_box);
Expand All @@ -221,38 +116,9 @@ void ControllersWindow::CreateMainLayout()
void ControllersWindow::ConnectWidgets()
{
connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
&ControllersWindow::UpdateDisabledWiimoteControls);

connect(m_wiimote_passthrough, &QRadioButton::toggled, this,
&ControllersWindow::OnWiimoteModeChanged);
connect(m_wiimote_ciface, &QCheckBox::toggled, this, &ControllersWindow::OnWiimoteModeChanged);
connect(m_wiimote_ciface, &QCheckBox::toggled, this,
&WiimoteReal::HandleWiimotesInControllerInterfaceSettingChange);
connect(m_wiimote_continuous_scanning, &QCheckBox::toggled, this,
&ControllersWindow::OnWiimoteModeChanged);

connect(m_wiimote_continuous_scanning, &QCheckBox::toggled, this,
&ControllersWindow::SaveSettings);
connect(m_wiimote_real_balance_board, &QCheckBox::toggled, this,
&ControllersWindow::SaveSettings);
connect(m_wiimote_speaker_data, &QCheckBox::toggled, this, &ControllersWindow::SaveSettings);
connect(m_wiimote_sync, &QPushButton::clicked, this,
&ControllersWindow::OnBluetoothPassthroughSyncPressed);
connect(m_wiimote_reset, &QPushButton::clicked, this,
&ControllersWindow::OnBluetoothPassthroughResetPressed);
connect(m_wiimote_refresh, &QPushButton::clicked, this,
&ControllersWindow::OnWiimoteRefreshPressed);

for (size_t i = 0; i < m_wiimote_groups.size(); i++)
{
connect(m_wiimote_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this,
&ControllersWindow::SaveSettings);
connect(m_wiimote_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this,
&ControllersWindow::OnWiimoteModeChanged);
connect(m_wiimote_buttons[i], &QPushButton::clicked, this,
&ControllersWindow::OnWiimoteConfigure);

for (size_t i = 0; i < m_gc_groups.size(); i++)
{
connect(m_gc_controller_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this,
&ControllersWindow::SaveSettings);
connect(m_gc_controller_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this,
Expand All @@ -261,52 +127,6 @@ void ControllersWindow::ConnectWidgets()
}
}

void ControllersWindow::OnWiimoteModeChanged()
{
SaveSettings();

// Make sure continuous scanning setting is applied.
WiimoteReal::Initialize(::Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);

UpdateDisabledWiimoteControls();
}

void ControllersWindow::UpdateDisabledWiimoteControls()
{
const bool running = Core::GetState() != Core::State::Uninitialized;

m_wiimote_emu->setEnabled(!running);
m_wiimote_passthrough->setEnabled(!running);

const bool running_gc = running && !SConfig::GetInstance().bWii;
const bool enable_passthrough = m_wiimote_passthrough->isChecked() && !running_gc;
const bool enable_emu_bt = !m_wiimote_passthrough->isChecked() && !running_gc;

m_wiimote_sync->setEnabled(enable_passthrough);
m_wiimote_reset->setEnabled(enable_passthrough);

for (auto* pt_label : m_wiimote_pt_labels)
pt_label->setEnabled(enable_passthrough);

for (size_t i = 0; i < m_wiimote_groups.size(); i++)
{
m_wiimote_labels[i]->setEnabled(enable_emu_bt);
m_wiimote_boxes[i]->setEnabled(enable_emu_bt);

const bool is_emu_wiimote = m_wiimote_boxes[i]->currentIndex() == 1;
m_wiimote_buttons[i]->setEnabled(enable_emu_bt && is_emu_wiimote);
}

m_wiimote_real_balance_board->setEnabled(enable_emu_bt);
m_wiimote_speaker_data->setEnabled(enable_emu_bt);

const bool ciface_wiimotes = m_wiimote_ciface->isChecked();

m_wiimote_refresh->setEnabled((enable_emu_bt || ciface_wiimotes) &&
!m_wiimote_continuous_scanning->isChecked());
m_wiimote_continuous_scanning->setEnabled(enable_emu_bt || ciface_wiimotes);
}

void ControllersWindow::OnGCTypeChanged(int type)
{
const auto* box = static_cast<QComboBox*>(QObject::sender());
Expand All @@ -324,50 +144,6 @@ void ControllersWindow::OnGCTypeChanged(int type)
SaveSettings();
}

void ControllersWindow::OnBluetoothPassthroughResetPressed()
{
const auto ios = IOS::HLE::GetIOS();

if (!ios)
{
ModalMessageBox::warning(
this, tr("Warning"),
tr("Saved Wii Remote pairings can only be reset when a Wii game is running."));
return;
}

auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305");
if (device != nullptr)
{
std::static_pointer_cast<IOS::HLE::Device::BluetoothBase>(device)->TriggerSyncButtonHeldEvent();
}
}

void ControllersWindow::OnBluetoothPassthroughSyncPressed()
{
const auto ios = IOS::HLE::GetIOS();

if (!ios)
{
ModalMessageBox::warning(this, tr("Warning"),
tr("A sync can only be triggered when a Wii game is running."));
return;
}

auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305");

if (device != nullptr)
{
std::static_pointer_cast<IOS::HLE::Device::BluetoothBase>(device)
->TriggerSyncButtonPressedEvent();
}
}

void ControllersWindow::OnWiimoteRefreshPressed()
{
WiimoteReal::Refresh();
}

void ControllersWindow::OnGCPadConfigure()
{
size_t index;
Expand Down Expand Up @@ -412,79 +188,21 @@ void ControllersWindow::OnGCPadConfigure()
window->show();
}

void ControllersWindow::OnWiimoteConfigure()
{
size_t index;
for (index = 0; index < m_wiimote_groups.size(); index++)
{
if (m_wiimote_buttons[index] == QObject::sender())
break;
}

MappingWindow::Type type;
switch (m_wiimote_boxes[index]->currentIndex())
{
case 0: // None
case 2: // Real Wii Remote
return;
case 1: // Emulated Wii Remote
type = MappingWindow::Type::MAPPING_WIIMOTE_EMU;
break;
default:
return;
}

MappingWindow* window = new MappingWindow(this, type, static_cast<int>(index));
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
window->show();
}

void ControllersWindow::LoadSettings()
{
for (size_t i = 0; i < m_wiimote_groups.size(); i++)
for (size_t i = 0; i < m_gc_groups.size(); i++)
{
const std::optional<int> gc_index = ToGCMenuIndex(SConfig::GetInstance().m_SIDevice[i]);
if (gc_index)
{
m_gc_controller_boxes[i]->setCurrentIndex(*gc_index);
m_gc_buttons[i]->setEnabled(*gc_index != 0 && *gc_index != 6);
}
m_wiimote_boxes[i]->setCurrentIndex(int(WiimoteCommon::GetSource(u32(i))));
}
m_wiimote_real_balance_board->setChecked(WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD) ==
WiimoteSource::Real);
m_wiimote_speaker_data->setChecked(SConfig::GetInstance().m_WiimoteEnableSpeaker);
m_wiimote_ciface->setChecked(SConfig::GetInstance().connect_wiimotes_for_ciface);
m_wiimote_continuous_scanning->setChecked(SConfig::GetInstance().m_WiimoteContinuousScanning);

if (SConfig::GetInstance().m_bt_passthrough_enabled)
m_wiimote_passthrough->setChecked(true);
else
m_wiimote_emu->setChecked(true);

OnWiimoteModeChanged();
}

void ControllersWindow::SaveSettings()
{
SConfig::GetInstance().m_WiimoteEnableSpeaker = m_wiimote_speaker_data->isChecked();
SConfig::GetInstance().connect_wiimotes_for_ciface = m_wiimote_ciface->isChecked();
SConfig::GetInstance().m_WiimoteContinuousScanning = m_wiimote_continuous_scanning->isChecked();
SConfig::GetInstance().m_bt_passthrough_enabled = m_wiimote_passthrough->isChecked();

WiimoteCommon::SetSource(WIIMOTE_BALANCE_BOARD, m_wiimote_real_balance_board->isChecked() ?
WiimoteSource::Real :
WiimoteSource::None);

for (size_t i = 0; i < m_wiimote_groups.size(); i++)
{
const int index = m_wiimote_boxes[i]->currentIndex();
WiimoteCommon::SetSource(u32(i), WiimoteSource(index));
}

UICommon::SaveWiimoteSources();

for (size_t i = 0; i < m_gc_groups.size(); i++)
{
const int index = m_gc_controller_boxes[i]->currentIndex();
Expand Down

0 comments on commit 920dd81

Please sign in to comment.