|
|
|
@ -10,6 +10,8 @@ |
|
|
|
#include <QStandardItemModel>
|
|
|
|
#include <QTimer>
|
|
|
|
#include "common/param_package.h"
|
|
|
|
#include "core/frontend/framebuffer_layout.h"
|
|
|
|
#include "core/settings.h"
|
|
|
|
#include "input_common/main.h"
|
|
|
|
#include "ui_configure_touch_from_button.h"
|
|
|
|
#include "yuzu/configuration/configure_touch_from_button.h"
|
|
|
|
@ -68,15 +70,16 @@ static QString ButtonToText(const Common::ParamPackage& param) { |
|
|
|
|
|
|
|
ConfigureTouchFromButton::ConfigureTouchFromButton( |
|
|
|
QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps, |
|
|
|
const int default_index) |
|
|
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), touch_maps(touch_maps), |
|
|
|
selected_index(default_index), timeout_timer(std::make_unique<QTimer>()), |
|
|
|
poll_timer(std::make_unique<QTimer>()) { |
|
|
|
InputCommon::InputSubsystem* input_subsystem_, const int default_index) |
|
|
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), |
|
|
|
touch_maps(touch_maps), input_subsystem{input_subsystem_}, selected_index(default_index), |
|
|
|
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { |
|
|
|
|
|
|
|
ui->setupUi(this); |
|
|
|
binding_list_model = std::make_unique<QStandardItemModel>(0, 3, this); |
|
|
|
binding_list_model->setHorizontalHeaderLabels({tr("Button"), tr("X"), tr("Y")}); |
|
|
|
ui->binding_list->setModel(binding_list_model.get()); |
|
|
|
binding_list_model = new QStandardItemModel(0, 3, this); |
|
|
|
binding_list_model->setHorizontalHeaderLabels( |
|
|
|
{tr("Button"), tr("X", "X axis"), tr("Y", "Y axis")}); |
|
|
|
ui->binding_list->setModel(binding_list_model); |
|
|
|
ui->bottom_screen->SetCoordLabel(ui->coord_label); |
|
|
|
|
|
|
|
SetConfiguration(); |
|
|
|
@ -92,12 +95,13 @@ void ConfigureTouchFromButton::showEvent(QShowEvent* ev) { |
|
|
|
// width values are not valid in the constructor
|
|
|
|
const int w = |
|
|
|
ui->binding_list->viewport()->contentsRect().width() / binding_list_model->columnCount(); |
|
|
|
if (w > 0) { |
|
|
|
if (w <= 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
ui->binding_list->setColumnWidth(0, w); |
|
|
|
ui->binding_list->setColumnWidth(1, w); |
|
|
|
ui->binding_list->setColumnWidth(2, w); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void ConfigureTouchFromButton::SetConfiguration() { |
|
|
|
for (const auto& touch_map : touch_maps) { |
|
|
|
@ -122,7 +126,7 @@ void ConfigureTouchFromButton::UpdateUiDisplay() { |
|
|
|
QStandardItem* ycoord = new QStandardItem(QString::number(package.Get("y", 0))); |
|
|
|
binding_list_model->appendRow({button, xcoord, ycoord}); |
|
|
|
|
|
|
|
int dot = ui->bottom_screen->AddDot(package.Get("x", 0), package.Get("y", 0)); |
|
|
|
const int dot = ui->bottom_screen->AddDot(package.Get("x", 0), package.Get("y", 0)); |
|
|
|
button->setData(dot, DataRoleDot); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -144,7 +148,7 @@ void ConfigureTouchFromButton::ConnectEvents() { |
|
|
|
&ConfigureTouchFromButton::EditBinding); |
|
|
|
connect(ui->binding_list->selectionModel(), &QItemSelectionModel::selectionChanged, this, |
|
|
|
&ConfigureTouchFromButton::OnBindingSelection); |
|
|
|
connect(binding_list_model.get(), &QStandardItemModel::itemChanged, this, |
|
|
|
connect(binding_list_model, &QStandardItemModel::itemChanged, this, |
|
|
|
&ConfigureTouchFromButton::OnBindingChanged); |
|
|
|
connect(ui->binding_list->model(), &QStandardItemModel::rowsAboutToBeRemoved, this, |
|
|
|
&ConfigureTouchFromButton::OnBindingDeleted); |
|
|
|
@ -231,7 +235,7 @@ void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is |
|
|
|
|
|
|
|
input_setter = [this, row_index, is_new](const Common::ParamPackage& params, |
|
|
|
const bool cancel) { |
|
|
|
auto cell = binding_list_model->item(row_index, 0); |
|
|
|
auto* cell = binding_list_model->item(row_index, 0); |
|
|
|
if (cancel) { |
|
|
|
if (is_new) { |
|
|
|
binding_list_model->removeRow(row_index); |
|
|
|
@ -245,7 +249,7 @@ void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
device_pollers = InputCommon::Polling::GetPollers(InputCommon::Polling::DeviceType::Button); |
|
|
|
device_pollers = input_subsystem->GetPollers(InputCommon::Polling::DeviceType::Button); |
|
|
|
|
|
|
|
for (auto& poller : device_pollers) { |
|
|
|
poller->Start(); |
|
|
|
@ -259,15 +263,15 @@ void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is |
|
|
|
} |
|
|
|
|
|
|
|
void ConfigureTouchFromButton::NewBinding(const QPoint& pos) { |
|
|
|
QStandardItem* button = new QStandardItem(); |
|
|
|
auto* button = new QStandardItem(); |
|
|
|
button->setEditable(false); |
|
|
|
QStandardItem* xcoord = new QStandardItem(QString::number(pos.x())); |
|
|
|
QStandardItem* ycoord = new QStandardItem(QString::number(pos.y())); |
|
|
|
auto* x_coord = new QStandardItem(QString::number(pos.x())); |
|
|
|
auto* y_coord = new QStandardItem(QString::number(pos.y())); |
|
|
|
|
|
|
|
const int dot_id = ui->bottom_screen->AddDot(pos.x(), pos.y()); |
|
|
|
button->setData(dot_id, DataRoleDot); |
|
|
|
|
|
|
|
binding_list_model->appendRow({button, xcoord, ycoord}); |
|
|
|
binding_list_model->appendRow({button, x_coord, y_coord}); |
|
|
|
ui->binding_list->setFocus(); |
|
|
|
ui->binding_list->setCurrentIndex(button->index()); |
|
|
|
|
|
|
|
@ -282,11 +286,11 @@ void ConfigureTouchFromButton::EditBinding(const QModelIndex& qi) { |
|
|
|
|
|
|
|
void ConfigureTouchFromButton::DeleteBinding() { |
|
|
|
const int row_index = ui->binding_list->currentIndex().row(); |
|
|
|
if (row_index >= 0) { |
|
|
|
ui->bottom_screen->RemoveDot( |
|
|
|
binding_list_model->index(row_index, 0).data(DataRoleDot).toInt()); |
|
|
|
binding_list_model->removeRow(row_index); |
|
|
|
if (row_index < 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
ui->bottom_screen->RemoveDot(binding_list_model->index(row_index, 0).data(DataRoleDot).toInt()); |
|
|
|
binding_list_model->removeRow(row_index); |
|
|
|
} |
|
|
|
|
|
|
|
void ConfigureTouchFromButton::OnBindingSelection(const QItemSelection& selected, |
|
|
|
@ -329,7 +333,7 @@ void ConfigureTouchFromButton::OnBindingChanged(QStandardItem* item) { |
|
|
|
|
|
|
|
void ConfigureTouchFromButton::OnBindingDeleted(const QModelIndex& parent, int first, int last) { |
|
|
|
for (int i = first; i <= last; ++i) { |
|
|
|
auto ix = binding_list_model->index(i, 0); |
|
|
|
const auto ix = binding_list_model->index(i, 0); |
|
|
|
if (!ix.isValid()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -422,7 +426,7 @@ int TouchScreenPreview::AddDot(const int device_x, const int device_y) { |
|
|
|
dot_font.setStyleHint(QFont::Monospace); |
|
|
|
dot_font.setPointSize(20); |
|
|
|
|
|
|
|
QLabel* dot = new QLabel(this); |
|
|
|
auto* dot = new QLabel(this); |
|
|
|
dot->setAttribute(Qt::WA_TranslucentBackground); |
|
|
|
dot->setFont(dot_font); |
|
|
|
dot->setText(QChar(0xD7)); // U+00D7 Multiplication Sign
|
|
|
|
@ -440,13 +444,14 @@ int TouchScreenPreview::AddDot(const int device_x, const int device_y) { |
|
|
|
} |
|
|
|
|
|
|
|
void TouchScreenPreview::RemoveDot(const int id) { |
|
|
|
for (auto dot_it = dots.begin(); dot_it != dots.end(); ++dot_it) { |
|
|
|
if (dot_it->first == id) { |
|
|
|
dot_it->second->deleteLater(); |
|
|
|
dots.erase(dot_it); |
|
|
|
const auto iter = std::find_if(dots.begin(), dots.end(), |
|
|
|
[id](const auto& entry) { return entry.first == id; }); |
|
|
|
if (iter == dots.cend()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
iter->second->deleteLater(); |
|
|
|
dots.erase(iter); |
|
|
|
} |
|
|
|
|
|
|
|
void TouchScreenPreview::HighlightDot(const int id, const bool active) const { |
|
|
|
@ -470,14 +475,15 @@ void TouchScreenPreview::HighlightDot(const int id, const bool active) const { |
|
|
|
} |
|
|
|
|
|
|
|
void TouchScreenPreview::MoveDot(const int id, const int device_x, const int device_y) const { |
|
|
|
for (const auto& dot : dots) { |
|
|
|
if (dot.first == id) { |
|
|
|
dot.second->setProperty(PropX, device_x); |
|
|
|
dot.second->setProperty(PropY, device_y); |
|
|
|
PositionDot(dot.second, device_x, device_y); |
|
|
|
const auto iter = std::find_if(dots.begin(), dots.end(), |
|
|
|
[id](const auto& entry) { return entry.first == id; }); |
|
|
|
if (iter == dots.cend()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
iter->second->setProperty(PropX, device_x); |
|
|
|
iter->second->setProperty(PropY, device_y); |
|
|
|
PositionDot(iter->second, device_x, device_y); |
|
|
|
} |
|
|
|
|
|
|
|
void TouchScreenPreview::resizeEvent(QResizeEvent* event) { |
|
|
|
@ -521,13 +527,14 @@ void TouchScreenPreview::leaveEvent(QEvent* event) { |
|
|
|
} |
|
|
|
|
|
|
|
void TouchScreenPreview::mousePressEvent(QMouseEvent* event) { |
|
|
|
if (event->button() == Qt::MouseButton::LeftButton) { |
|
|
|
if (event->button() != Qt::MouseButton::LeftButton) { |
|
|
|
return; |
|
|
|
} |
|
|
|
const auto pos = MapToDeviceCoords(event->x(), event->y()); |
|
|
|
if (pos) { |
|
|
|
emit DotAdded(*pos); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool TouchScreenPreview::eventFilter(QObject* obj, QEvent* event) { |
|
|
|
switch (event->type()) { |
|
|
|
@ -601,12 +608,17 @@ std::optional<QPoint> TouchScreenPreview::MapToDeviceCoords(const int screen_x, |
|
|
|
|
|
|
|
void TouchScreenPreview::PositionDot(QLabel* const dot, const int device_x, |
|
|
|
const int device_y) const { |
|
|
|
dot->move(static_cast<int>( |
|
|
|
static_cast<float>(device_x >= 0 ? device_x : dot->property(PropX).toInt()) * |
|
|
|
(contentsRect().width() - 1) / (Layout::ScreenUndocked::Width - 1) + |
|
|
|
contentsMargins().left() - static_cast<float>(dot->width()) / 2 + 0.5f), |
|
|
|
static_cast<int>( |
|
|
|
static_cast<float>(device_y >= 0 ? device_y : dot->property(PropY).toInt()) * |
|
|
|
(contentsRect().height() - 1) / (Layout::ScreenUndocked::Height - 1) + |
|
|
|
contentsMargins().top() - static_cast<float>(dot->height()) / 2 + 0.5f)); |
|
|
|
const float device_coord_x = |
|
|
|
static_cast<float>(device_x >= 0 ? device_x : dot->property(PropX).toInt()); |
|
|
|
int x_coord = static_cast<int>( |
|
|
|
device_coord_x * (contentsRect().width() - 1) / (Layout::ScreenUndocked::Width - 1) + |
|
|
|
contentsMargins().left() - static_cast<float>(dot->width()) / 2 + 0.5f); |
|
|
|
|
|
|
|
const float device_coord_y = |
|
|
|
static_cast<float>(device_y >= 0 ? device_y : dot->property(PropY).toInt()); |
|
|
|
const int y_coord = static_cast<int>( |
|
|
|
device_coord_y * (contentsRect().height() - 1) / (Layout::ScreenUndocked::Height - 1) + |
|
|
|
contentsMargins().top() - static_cast<float>(dot->height()) / 2 + 0.5f); |
|
|
|
|
|
|
|
dot->move(x_coord, y_coord); |
|
|
|
} |