diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt
index 78a842f2bc..e9d24bc4d1 100644
--- a/Source/Core/DolphinQt/CMakeLists.txt
+++ b/Source/Core/DolphinQt/CMakeLists.txt
@@ -343,6 +343,8 @@ add_executable(dolphin-emu
TAS/TASInputWindow.h
TAS/TASSlider.cpp
TAS/TASSlider.h
+ TAS/TASSpinBox.cpp
+ TAS/TASSpinBox.h
TAS/WiiTASInputWindow.cpp
TAS/WiiTASInputWindow.h
ToolBar.cpp
diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj
index 76b01c95d7..838e33d7a1 100644
--- a/Source/Core/DolphinQt/DolphinQt.vcxproj
+++ b/Source/Core/DolphinQt/DolphinQt.vcxproj
@@ -209,6 +209,7 @@
+
@@ -389,6 +390,7 @@
+
diff --git a/Source/Core/DolphinQt/TAS/TASInputWindow.cpp b/Source/Core/DolphinQt/TAS/TASInputWindow.cpp
index 047b554b38..d74a84997f 100644
--- a/Source/Core/DolphinQt/TAS/TASInputWindow.cpp
+++ b/Source/Core/DolphinQt/TAS/TASInputWindow.cpp
@@ -23,6 +23,7 @@
#include "DolphinQt/TAS/StickWidget.h"
#include "DolphinQt/TAS/TASCheckBox.h"
#include "DolphinQt/TAS/TASSlider.h"
+#include "DolphinQt/TAS/TASSpinBox.h"
#include "InputCommon/ControllerEmu/ControllerEmu.h"
#include "InputCommon/ControllerEmu/StickGate.h"
@@ -109,11 +110,11 @@ QGroupBox* TASInputWindow::CreateStickInputs(const QString& text, std::string_vi
const int y_default = static_cast(std::round(max_y / 2.));
auto* x_layout = new QHBoxLayout;
- QSpinBox* x_value = CreateSliderValuePair(x_layout, x_default, max_x, x_shortcut_key_sequence,
- Qt::Horizontal, box);
+ TASSpinBox* x_value = CreateSliderValuePair(x_layout, x_default, max_x, x_shortcut_key_sequence,
+ Qt::Horizontal, box);
auto* y_layout = new QVBoxLayout;
- QSpinBox* y_value =
+ TASSpinBox* y_value =
CreateSliderValuePair(y_layout, y_default, max_y, y_shortcut_key_sequence, Qt::Vertical, box);
y_value->setMaximumWidth(60);
@@ -169,14 +170,14 @@ QBoxLayout* TASInputWindow::CreateSliderValuePairLayout(
return layout;
}
-QSpinBox* TASInputWindow::CreateSliderValuePair(
+TASSpinBox* TASInputWindow::CreateSliderValuePair(
std::string_view group_name, std::string_view control_name, InputOverrider* overrider,
QBoxLayout* layout, u16 zero, int default_, u16 min, u16 max,
QKeySequence shortcut_key_sequence, Qt::Orientation orientation, QWidget* shortcut_widget,
std::optional scale)
{
- QSpinBox* value = CreateSliderValuePair(layout, default_, max, shortcut_key_sequence, orientation,
- shortcut_widget);
+ TASSpinBox* value = CreateSliderValuePair(layout, default_, max, shortcut_key_sequence,
+ orientation, shortcut_widget);
InputOverrider::OverrideFunction func;
if (scale)
@@ -199,12 +200,12 @@ QSpinBox* TASInputWindow::CreateSliderValuePair(
// The shortcut_widget argument needs to specify the container widget that will be hidden/shown.
// This is done to avoid ambigous shortcuts
-QSpinBox* TASInputWindow::CreateSliderValuePair(QBoxLayout* layout, int default_, u16 max,
- QKeySequence shortcut_key_sequence,
- Qt::Orientation orientation,
- QWidget* shortcut_widget)
+TASSpinBox* TASInputWindow::CreateSliderValuePair(QBoxLayout* layout, int default_, u16 max,
+ QKeySequence shortcut_key_sequence,
+ Qt::Orientation orientation,
+ QWidget* shortcut_widget)
{
- auto* value = new QSpinBox();
+ auto* value = new TASSpinBox();
value->setRange(0, 99999);
value->setValue(default_);
connect(value, qOverload(&QSpinBox::valueChanged), [value, max](int i) {
@@ -243,51 +244,27 @@ std::optional TASInputWindow::GetButton(TASCheckBox* checkbox,
return checkbox->GetValue() ? 1.0 : 0.0;
}
-std::optional TASInputWindow::GetSpinBox(QSpinBox* spin, u16 zero, u16 min, u16 max,
+std::optional TASInputWindow::GetSpinBox(TASSpinBox* spin, u16 zero, u16 min, u16 max,
ControlState controller_state)
{
const u16 controller_value =
ControllerEmu::EmulatedController::MapFloat(controller_state, zero, 0, max);
if (m_use_controller->isChecked())
- {
- if (!m_spinbox_most_recent_values.count(spin) ||
- m_spinbox_most_recent_values[spin] != controller_value)
- {
- QueueOnObjectBlocking(spin, [spin, controller_value] { spin->setValue(controller_value); });
- }
+ spin->OnControllerValueChanged(controller_value);
- m_spinbox_most_recent_values[spin] = controller_value;
- }
- else
- {
- m_spinbox_most_recent_values.clear();
- }
-
- return ControllerEmu::EmulatedController::MapToFloat(spin->value(), zero, min,
- max);
+ return ControllerEmu::EmulatedController::MapToFloat(spin->GetValue(), zero,
+ min, max);
}
-std::optional TASInputWindow::GetSpinBox(QSpinBox* spin, u16 zero,
+std::optional TASInputWindow::GetSpinBox(TASSpinBox* spin, u16 zero,
ControlState controller_state,
ControlState scale)
{
const u16 controller_value = static_cast(std::llround(controller_state * scale + zero));
if (m_use_controller->isChecked())
- {
- if (!m_spinbox_most_recent_values.count(spin) ||
- m_spinbox_most_recent_values[spin] != controller_value)
- {
- QueueOnObjectBlocking(spin, [spin, controller_value] { spin->setValue(controller_value); });
- }
+ spin->OnControllerValueChanged(controller_value);
- m_spinbox_most_recent_values[spin] = controller_value;
- }
- else
- {
- m_spinbox_most_recent_values.clear();
- }
-
- return (spin->value() - zero) / scale;
+ return (spin->GetValue() - zero) / scale;
}
diff --git a/Source/Core/DolphinQt/TAS/TASInputWindow.h b/Source/Core/DolphinQt/TAS/TASInputWindow.h
index 15aea29443..45d84ba014 100644
--- a/Source/Core/DolphinQt/TAS/TASInputWindow.h
+++ b/Source/Core/DolphinQt/TAS/TASInputWindow.h
@@ -22,6 +22,7 @@ class QGroupBox;
class QSpinBox;
class QString;
class TASCheckBox;
+class TASSpinBox;
class InputOverrider final
{
@@ -57,14 +58,15 @@ protected:
u16 zero, int default_, u16 min, u16 max,
Qt::Key shortcut_key, QWidget* shortcut_widget,
std::optional scale = {});
- QSpinBox* CreateSliderValuePair(std::string_view group_name, std::string_view control_name,
- InputOverrider* overrider, QBoxLayout* layout, u16 zero,
- int default_, u16 min, u16 max,
- QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
- QWidget* shortcut_widget, std::optional scale = {});
- QSpinBox* CreateSliderValuePair(QBoxLayout* layout, int default_, u16 max,
- QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
- QWidget* shortcut_widget);
+ TASSpinBox* CreateSliderValuePair(std::string_view group_name, std::string_view control_name,
+ InputOverrider* overrider, QBoxLayout* layout, u16 zero,
+ int default_, u16 min, u16 max,
+ QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
+ QWidget* shortcut_widget,
+ std::optional scale = {});
+ TASSpinBox* CreateSliderValuePair(QBoxLayout* layout, int default_, u16 max,
+ QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
+ QWidget* shortcut_widget);
QGroupBox* m_settings_box;
QCheckBox* m_use_controller;
@@ -73,10 +75,8 @@ protected:
private:
std::optional GetButton(TASCheckBox* checkbox, ControlState controller_state);
- std::optional GetSpinBox(QSpinBox* spin, u16 zero, u16 min, u16 max,
+ std::optional GetSpinBox(TASSpinBox* spin, u16 zero, u16 min, u16 max,
ControlState controller_state);
- std::optional GetSpinBox(QSpinBox* spin, u16 zero, ControlState controller_state,
+ std::optional GetSpinBox(TASSpinBox* spin, u16 zero, ControlState controller_state,
ControlState scale);
-
- std::map m_spinbox_most_recent_values;
};
diff --git a/Source/Core/DolphinQt/TAS/TASSpinBox.cpp b/Source/Core/DolphinQt/TAS/TASSpinBox.cpp
new file mode 100644
index 0000000000..30c3618b26
--- /dev/null
+++ b/Source/Core/DolphinQt/TAS/TASSpinBox.cpp
@@ -0,0 +1,33 @@
+// Copyright 2019 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "DolphinQt/TAS/TASSpinBox.h"
+
+#include "DolphinQt/QtUtils/QueueOnObject.h"
+
+TASSpinBox::TASSpinBox(QWidget* parent) : QSpinBox(parent)
+{
+ connect(this, QOverload::of(&TASSpinBox::valueChanged), this, &TASSpinBox::OnUIValueChanged);
+}
+
+int TASSpinBox::GetValue() const
+{
+ return m_state.GetValue();
+}
+
+void TASSpinBox::OnControllerValueChanged(int new_value)
+{
+ if (m_state.OnControllerValueChanged(static_cast(new_value)))
+ QueueOnObject(this, &TASSpinBox::ApplyControllerValueChange);
+}
+
+void TASSpinBox::OnUIValueChanged(int new_value)
+{
+ m_state.OnUIValueChanged(static_cast(new_value));
+}
+
+void TASSpinBox::ApplyControllerValueChange()
+{
+ const QSignalBlocker blocker(this);
+ setValue(m_state.ApplyControllerValueChange());
+}
diff --git a/Source/Core/DolphinQt/TAS/TASSpinBox.h b/Source/Core/DolphinQt/TAS/TASSpinBox.h
new file mode 100644
index 0000000000..55908911d7
--- /dev/null
+++ b/Source/Core/DolphinQt/TAS/TASSpinBox.h
@@ -0,0 +1,29 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include
+
+#include "DolphinQt/TAS/TASControlState.h"
+
+class TASInputWindow;
+
+class TASSpinBox : public QSpinBox
+{
+ Q_OBJECT
+public:
+ explicit TASSpinBox(QWidget* parent = nullptr);
+
+ // Can be called from the CPU thread
+ int GetValue() const;
+ // Must be called from the CPU thread
+ void OnControllerValueChanged(int new_value);
+
+private slots:
+ void OnUIValueChanged(int new_value);
+ void ApplyControllerValueChange();
+
+private:
+ TASControlState m_state;
+};
diff --git a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp
index c38e340912..b6e54fb6da 100644
--- a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp
+++ b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp
@@ -29,6 +29,7 @@
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/TAS/IRWidget.h"
#include "DolphinQt/TAS/TASCheckBox.h"
+#include "DolphinQt/TAS/TASSpinBox.h"
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
#include "InputCommon/ControllerEmu/ControllerEmu.h"
diff --git a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.h b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.h
index ef01906741..63ce0fb4df 100644
--- a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.h
+++ b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.h
@@ -12,6 +12,7 @@ class QHideEvent;
class QShowEvent;
class QSpinBox;
class TASCheckBox;
+class TASSpinBox;
namespace WiimoteEmu
{
@@ -75,8 +76,8 @@ private:
TASCheckBox* m_classic_up_button;
TASCheckBox* m_classic_down_button;
TASCheckBox* m_classic_right_button;
- QSpinBox* m_ir_x_value;
- QSpinBox* m_ir_y_value;
+ TASSpinBox* m_ir_x_value;
+ TASSpinBox* m_ir_y_value;
QGroupBox* m_remote_orientation_box;
QGroupBox* m_nunchuk_orientation_box;
QGroupBox* m_ir_box;