Skip to content

Commit

Permalink
Redo balance board TAS input
Browse files Browse the repository at this point in the history
  • Loading branch information
Pokechu22 committed Jan 28, 2021
1 parent 9639e95 commit 1076c14
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 78 deletions.
95 changes: 78 additions & 17 deletions Source/Core/DolphinQt/TAS/BalanceBoardWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,67 @@
BalanceBoardWidget::BalanceBoardWidget(QWidget* parent) : QWidget(parent)
{
setMouseTracking(false);
setToolTip(tr("Left click to set the IR value.\n"
"Right click to re-center it."));
setToolTip(tr("Left click to set the balance value.\n"
"Right click to return to perfect balance."));
}

void BalanceBoardWidget::SetX(u16 x)
void BalanceBoardWidget::SetTR(double top_right)
{
m_x = std::min(balance_range, x);
m_top_right = top_right;
emit ChangedTotal(TotalWeight());
update();
}

void BalanceBoardWidget::SetBR(double bottom_right)
{
m_bottom_right = bottom_right;
emit ChangedTotal(TotalWeight());
update();
}

void BalanceBoardWidget::SetY(u16 y)
void BalanceBoardWidget::SetTL(double top_left)
{
m_y = std::min(balance_range, y);
m_top_left = top_left;
emit ChangedTotal(TotalWeight());
update();
}

void BalanceBoardWidget::SetBL(double bottom_left)
{
m_bottom_left = bottom_left;
emit ChangedTotal(TotalWeight());
update();
}

void BalanceBoardWidget::SetTotal(double total)
{
const double current_total = TotalWeight();
if (current_total != 0)
{
const double ratio = total / current_total;
m_top_right *= ratio;
m_bottom_right *= ratio;
m_top_left *= ratio;
m_bottom_left *= ratio;
}
else
{
m_top_right = total / 4;
m_bottom_right = total / 4;
m_top_left = total / 4;
m_bottom_left = total / 4;
}
emit ChangedTR(m_top_right);
emit ChangedBR(m_bottom_right);
emit ChangedTL(m_top_left);
emit ChangedBL(m_bottom_left);

const double new_total = TotalWeight();
if (new_total != total)
{
// This probably shouldn't happen, and I probably should round out numbers a bit closer
emit ChangedTotal(new_total);
}
update();
}

Expand All @@ -46,9 +92,17 @@ void BalanceBoardWidget::paintEvent(QPaintEvent* event)
painter.drawLine(0, height() / 2, width(), height() / 2);
painter.drawLine(width() / 2, 0, width() / 2, height());

// convert from value space to widget space
const int x = (m_x * width()) / balance_range;
const int y = height() - (m_y * height()) / balance_range;
// Compute center of balance
const double total = TotalWeight();
const double right = m_top_right + m_bottom_right;
const double left = m_top_left + m_bottom_left;
const double top = m_top_right + m_top_left;
const double bottom = m_bottom_right + m_bottom_left;
const double com_x = (total != 0) ? (right - left) / total : 0;
const double com_y = (total != 0) ? (top - bottom) / total : 0;

const int x = (int)((com_x + 1) * width() / 2);
const int y = (int)((1 - com_y) * height() / 2);

painter.drawLine(width() / 2, height() / 2, x, y);

Expand All @@ -72,22 +126,29 @@ void BalanceBoardWidget::mouseMoveEvent(QMouseEvent* event)

void BalanceBoardWidget::handleMouseEvent(QMouseEvent* event)
{
const double total = TotalWeight();
if (event->button() == Qt::RightButton)
{
m_x = std::round(balance_range / 2.);
m_y = std::round(balance_range / 2.);
m_top_right = total / 4;
m_bottom_right = total / 4;
m_top_left = total / 4;
m_bottom_left = total / 4;
}
else
{
// convert from widget space to value space
const int new_x = (event->x() * balance_range) / width();
const int new_y = balance_range - (event->y() * balance_range) / height();
const double com_x = std::clamp((event->x() * 2.) / width() - 1, -1., 1.);
const double com_y = std::clamp(1 - (event->y() * 2.) / height(), -1., 1.);

m_x = std::max(0, std::min(static_cast<int>(balance_range), new_x));
m_y = std::max(0, std::min(static_cast<int>(balance_range), new_y));
m_top_right = total * (1 + com_x + com_y) / 4;
m_bottom_right = total * (1 + com_x - com_y) / 4;
m_top_left = total * (1 - com_x + com_y) / 4;
m_bottom_left = total * (1 - com_x - com_y) / 4;
}

emit ChangedX(m_x);
emit ChangedY(m_y);
emit ChangedTR(m_top_right);
emit ChangedBR(m_bottom_right);
emit ChangedTL(m_top_left);
emit ChangedBL(m_bottom_left);
update();
}
23 changes: 15 additions & 8 deletions Source/Core/DolphinQt/TAS/BalanceBoardWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ class BalanceBoardWidget : public QWidget
public:
explicit BalanceBoardWidget(QWidget* parent);

static constexpr u16 balance_range = 1000;

signals:
void ChangedX(u16 x);
void ChangedY(u16 y);
void ChangedTR(double top_right);
void ChangedBR(double bottom_right);
void ChangedTL(double top_left);
void ChangedBL(double bottom_left);
void ChangedTotal(double total_weight);

public slots:
void SetX(u16 x);
void SetY(u16 y);
void SetTR(double top_right);
void SetBR(double bottom_right);
void SetTL(double top_left);
void SetBL(double bottom_left);
void SetTotal(double total_weight);

protected:
void paintEvent(QPaintEvent* event) override;
Expand All @@ -31,7 +35,10 @@ public slots:
void handleMouseEvent(QMouseEvent* event);

private:
u16 m_x = 0;
u16 m_y = 0;
double TotalWeight() { return m_top_right + m_bottom_right + m_top_left + m_bottom_left; }
double m_top_right = 0;
double m_bottom_right = 0;
double m_top_left = 0;
double m_bottom_left = 0;
bool m_ignore_movement = false;
};
38 changes: 36 additions & 2 deletions Source/Core/DolphinQt/TAS/TASInputWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cmath>

#include <QCheckBox>
#include <QDoubleSpinBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
Expand Down Expand Up @@ -116,8 +117,8 @@ QGroupBox* TASInputWindow::CreateStickInputs(QString name, QSpinBox*& x_value, Q
return box;
}

QBoxLayout* TASInputWindow::CreateSliderValuePairLayout(QString name, QSpinBox*& value, int default_, u16 max,
Qt::Key shortcut_key,
QBoxLayout* TASInputWindow::CreateSliderValuePairLayout(QString name, QSpinBox*& value,
int default_, u16 max, Qt::Key shortcut_key,
QWidget* shortcut_widget, bool invert)
{
const QKeySequence shortcut_key_sequence = QKeySequence(Qt::ALT + shortcut_key);
Expand Down Expand Up @@ -171,6 +172,39 @@ QSpinBox* TASInputWindow::CreateSliderValuePair(QBoxLayout* layout, int default_
return value;
}

// The shortcut_widget argument needs to specify the container widget that will be hidden/shown.
// This is done to avoid ambigous shortcuts
QDoubleSpinBox* TASInputWindow::CreateWeightSliderValuePair(QBoxLayout* layout, int min, int max,
QKeySequence shortcut_key_sequence,
QWidget* shortcut_widget)
{
auto* value = new QDoubleSpinBox();
value->setRange(min, max);
value->setDecimals(2);
value->setSuffix(QStringLiteral("kg"));
auto* slider = new QSlider(Qt::Orientation::Horizontal);
slider->setRange(min * 100, max * 100);
slider->setFocusPolicy(Qt::ClickFocus);
slider->setSingleStep(100);
slider->setPageStep(1000);
slider->setTickPosition(QSlider::TickPosition::TicksBelow);

connect(slider, &QSlider::valueChanged, value, [value](int i) { value->setValue(i / 100.0); });
connect(value, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
slider, [slider](double d) { slider->setValue((int)(d * 100)); });

auto* shortcut = new QShortcut(shortcut_key_sequence, shortcut_widget);
connect(shortcut, &QShortcut::activated, [value] {
value->setFocus();
value->selectAll();
});

layout->addWidget(slider);
layout->addWidget(value);

return value;
}

template <typename UX>
void TASInputWindow::GetButton(TASCheckBox* checkbox, UX& buttons, UX mask)
{
Expand Down
6 changes: 5 additions & 1 deletion Source/Core/DolphinQt/TAS/TASInputWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
struct GCPadStatus;
class QBoxLayout;
class QCheckBox;
class QDialog;
class QDoubleSpinBox;
class QGroupBox;
class QSpinBox;
class QString;
Expand All @@ -36,6 +36,10 @@ class TASInputWindow : public QDialog
QSpinBox* CreateSliderValuePair(QBoxLayout* layout, int default_, u16 max,
QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
QWidget* shortcut_widget, bool invert = false);
QDoubleSpinBox* CreateWeightSliderValuePair(QBoxLayout* layout, int min, int max,
QKeySequence shortcut_key_sequence,
QWidget* shortcut_widget);

template <typename UX>
void GetButton(TASCheckBox* button, UX& pad, UX mask);
void GetSpinBoxU8(QSpinBox* spin, u8& controller_value);
Expand Down
Loading

0 comments on commit 1076c14

Please sign in to comment.