mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-08 20:45:34 +00:00
Qt: Add icons/decorations to input devices
This commit is contained in:
parent
2298227054
commit
2d63b34d48
@ -272,11 +272,12 @@ void ControllerBindingWidget::onAutomaticBindingClicked()
|
|||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
|
||||||
for (const auto& [identifier, device_name] : g_emu_thread->getInputDeviceListModel()->getDeviceList())
|
for (const InputDeviceListModel::Device& dev : g_emu_thread->getInputDeviceListModel()->getDeviceList())
|
||||||
{
|
{
|
||||||
// we set it as data, because the device list could get invalidated while the menu is up
|
// we set it as data, because the device list could get invalidated while the menu is up
|
||||||
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(identifier).arg(device_name));
|
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.identifier).arg(dev.display_name));
|
||||||
action->setData(identifier);
|
action->setIcon(InputDeviceListModel::getIconForKey(dev.key));
|
||||||
|
action->setData(dev.identifier);
|
||||||
connect(action, &QAction::triggered, this,
|
connect(action, &QAction::triggered, this,
|
||||||
[this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
|
[this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
|
||||||
added = true;
|
added = true;
|
||||||
|
@ -140,6 +140,7 @@ void QtHost::RegisterTypes()
|
|||||||
qRegisterMetaType<RenderAPI>("RenderAPI");
|
qRegisterMetaType<RenderAPI>("RenderAPI");
|
||||||
qRegisterMetaType<GPURenderer>("GPURenderer");
|
qRegisterMetaType<GPURenderer>("GPURenderer");
|
||||||
qRegisterMetaType<InputBindingKey>("InputBindingKey");
|
qRegisterMetaType<InputBindingKey>("InputBindingKey");
|
||||||
|
qRegisterMetaType<InputDeviceListModel::Device>("InputDeviceListModel::Device");
|
||||||
qRegisterMetaType<std::string>("std::string");
|
qRegisterMetaType<std::string>("std::string");
|
||||||
qRegisterMetaType<std::vector<std::pair<std::string, std::string>>>(
|
qRegisterMetaType<std::vector<std::pair<std::string, std::string>>>(
|
||||||
"std::vector<std::pair<std::string, std::string>>");
|
"std::vector<std::pair<std::string, std::string>>");
|
||||||
@ -2007,6 +2008,16 @@ InputDeviceListModel::InputDeviceListModel(QObject* parent) : QAbstractListModel
|
|||||||
|
|
||||||
InputDeviceListModel::~InputDeviceListModel() = default;
|
InputDeviceListModel::~InputDeviceListModel() = default;
|
||||||
|
|
||||||
|
QIcon InputDeviceListModel::getIconForKey(const InputBindingKey& key)
|
||||||
|
{
|
||||||
|
if (key.source_type == InputSourceType::Keyboard)
|
||||||
|
return QIcon::fromTheme("keyboard-line");
|
||||||
|
else if (key.source_type == InputSourceType::Pointer)
|
||||||
|
return QIcon::fromTheme("mouse-line");
|
||||||
|
else
|
||||||
|
return QIcon::fromTheme("controller-line");
|
||||||
|
}
|
||||||
|
|
||||||
int InputDeviceListModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const
|
int InputDeviceListModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const
|
||||||
{
|
{
|
||||||
return m_devices.size();
|
return m_devices.size();
|
||||||
@ -2018,11 +2029,31 @@ QVariant InputDeviceListModel::data(const QModelIndex& index, int role /*= Qt::D
|
|||||||
if (index.column() != 0 || row < 0 || static_cast<qsizetype>(row) >= m_devices.size())
|
if (index.column() != 0 || row < 0 || static_cast<qsizetype>(row) >= m_devices.size())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
const auto& dev = m_devices[static_cast<qsizetype>(row)];
|
|
||||||
if (role == Qt::DisplayRole)
|
if (role == Qt::DisplayRole)
|
||||||
return QStringLiteral("%1: %2").arg(dev.first).arg(dev.second);
|
{
|
||||||
|
const auto& dev = m_devices[static_cast<qsizetype>(row)];
|
||||||
|
const InputBindingKey key = dev.key;
|
||||||
|
|
||||||
|
// don't display device names for implicit keyboard/mouse
|
||||||
|
if (key.source_type == InputSourceType::Keyboard ||
|
||||||
|
(key.source_type == InputSourceType::Pointer && !InputManager::IsUsingRawInput()))
|
||||||
|
{
|
||||||
|
return dev.display_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QStringLiteral("%1\n%2").arg(dev.identifier).arg(dev.display_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (role == Qt::DecorationRole)
|
||||||
|
{
|
||||||
|
const auto& dev = m_devices[static_cast<qsizetype>(row)];
|
||||||
|
return getIconForKey(dev.key);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputDeviceListModel::enumerateDevices()
|
void InputDeviceListModel::enumerateDevices()
|
||||||
@ -2035,7 +2066,7 @@ void InputDeviceListModel::enumerateDevices()
|
|||||||
DeviceList new_devices;
|
DeviceList new_devices;
|
||||||
new_devices.reserve(devices.size());
|
new_devices.reserve(devices.size());
|
||||||
for (const auto& [key, identifier, device_name] : devices)
|
for (const auto& [key, identifier, device_name] : devices)
|
||||||
new_devices.emplace_back(QString::fromStdString(identifier), QString::fromStdString(device_name));
|
new_devices.emplace_back(key, QString::fromStdString(identifier), QString::fromStdString(device_name));
|
||||||
|
|
||||||
QStringList new_motors;
|
QStringList new_motors;
|
||||||
new_motors.reserve(motors.size());
|
new_motors.reserve(motors.size());
|
||||||
@ -2059,28 +2090,28 @@ void InputDeviceListModel::resetLists(const DeviceList& devices, const QStringLi
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputDeviceListModel::onDeviceConnected(const QString& identifier, const QString& device_name,
|
void InputDeviceListModel::onDeviceConnected(const InputBindingKey& key, const QString& identifier,
|
||||||
const QStringList& vibration_motors)
|
const QString& device_name, const QStringList& vibration_motors)
|
||||||
{
|
{
|
||||||
for (const auto& it : m_devices)
|
for (const auto& it : m_devices)
|
||||||
{
|
{
|
||||||
if (it.first == identifier)
|
if (it.identifier == identifier)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int index = static_cast<int>(m_devices.size());
|
const int index = static_cast<int>(m_devices.size());
|
||||||
beginInsertRows(QModelIndex(), index, index);
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
m_devices.emplace_back(identifier, device_name);
|
m_devices.emplace_back(key, identifier, device_name);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
m_vibration_motors.append(vibration_motors);
|
m_vibration_motors.append(vibration_motors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputDeviceListModel::onDeviceDisconnected(const QString& identifier)
|
void InputDeviceListModel::onDeviceDisconnected(const InputBindingKey& key, const QString& identifier)
|
||||||
{
|
{
|
||||||
for (qsizetype i = 0; i < m_devices.size(); i++)
|
for (qsizetype i = 0; i < m_devices.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_devices[i].first == identifier)
|
if (m_devices[i].identifier == identifier)
|
||||||
{
|
{
|
||||||
const int index = static_cast<int>(i);
|
const int index = static_cast<int>(i);
|
||||||
beginRemoveRows(QModelIndex(), index, index);
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
@ -2117,10 +2148,10 @@ void Host::OnInputDeviceConnected(InputBindingKey key, std::string_view identifi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(g_emu_thread->getInputDeviceListModel(), "onDeviceConnected", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(
|
||||||
Q_ARG(const QString&, QtUtils::StringViewToQString(identifier)),
|
g_emu_thread->getInputDeviceListModel(), "onDeviceConnected", Qt::QueuedConnection,
|
||||||
Q_ARG(const QString&, QtUtils::StringViewToQString(device_name)),
|
Q_ARG(const InputBindingKey&, key), Q_ARG(const QString&, QtUtils::StringViewToQString(identifier)),
|
||||||
Q_ARG(const QStringList&, vibration_motor_list));
|
Q_ARG(const QString&, QtUtils::StringViewToQString(device_name)), Q_ARG(const QStringList&, vibration_motor_list));
|
||||||
|
|
||||||
if (System::IsValid() || GPUThread::IsFullscreenUIRequested())
|
if (System::IsValid() || GPUThread::IsFullscreenUIRequested())
|
||||||
{
|
{
|
||||||
@ -2133,6 +2164,7 @@ void Host::OnInputDeviceConnected(InputBindingKey key, std::string_view identifi
|
|||||||
void Host::OnInputDeviceDisconnected(InputBindingKey key, std::string_view identifier)
|
void Host::OnInputDeviceDisconnected(InputBindingKey key, std::string_view identifier)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(g_emu_thread->getInputDeviceListModel(), "onDeviceDisconnected", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(g_emu_thread->getInputDeviceListModel(), "onDeviceDisconnected", Qt::QueuedConnection,
|
||||||
|
Q_ARG(const InputBindingKey&, key),
|
||||||
Q_ARG(const QString&, QtUtils::StringViewToQString(identifier)));
|
Q_ARG(const QString&, QtUtils::StringViewToQString(identifier)));
|
||||||
|
|
||||||
if (g_settings.pause_on_controller_disconnection && System::GetState() == System::State::Running &&
|
if (g_settings.pause_on_controller_disconnection && System::GetState() == System::State::Running &&
|
||||||
|
@ -266,7 +266,14 @@ class InputDeviceListModel final : public QAbstractListModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using DeviceList = QList<QPair<QString, QString>>;
|
struct Device
|
||||||
|
{
|
||||||
|
InputBindingKey key;
|
||||||
|
QString identifier;
|
||||||
|
QString display_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
using DeviceList = QList<Device>;
|
||||||
|
|
||||||
InputDeviceListModel(QObject* parent = nullptr);
|
InputDeviceListModel(QObject* parent = nullptr);
|
||||||
~InputDeviceListModel() override;
|
~InputDeviceListModel() override;
|
||||||
@ -275,6 +282,8 @@ public:
|
|||||||
ALWAYS_INLINE const DeviceList& getDeviceList() const { return m_devices; }
|
ALWAYS_INLINE const DeviceList& getDeviceList() const { return m_devices; }
|
||||||
ALWAYS_INLINE const QStringList& getVibrationMotorList() const { return m_vibration_motors; }
|
ALWAYS_INLINE const QStringList& getVibrationMotorList() const { return m_vibration_motors; }
|
||||||
|
|
||||||
|
static QIcon getIconForKey(const InputBindingKey& key);
|
||||||
|
|
||||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
@ -282,8 +291,9 @@ public:
|
|||||||
void enumerateDevices();
|
void enumerateDevices();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onDeviceConnected(const QString& identifier, const QString& device_name, const QStringList& vibration_motors);
|
void onDeviceConnected(const InputBindingKey& key, const QString& identifier, const QString& device_name,
|
||||||
void onDeviceDisconnected(const QString& identifier);
|
const QStringList& vibration_motors);
|
||||||
|
void onDeviceDisconnected(const InputBindingKey& key, const QString& identifier);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void resetLists(const DeviceList& devices, const QStringList& motors);
|
void resetLists(const DeviceList& devices, const QStringList& motors);
|
||||||
|
@ -442,11 +442,12 @@ void SetupWizardDialog::openAutomaticMappingMenu(u32 port, QLabel* update_label)
|
|||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
|
||||||
for (const auto& [identifier, device_name] : g_emu_thread->getInputDeviceListModel()->getDeviceList())
|
for (const InputDeviceListModel::Device& dev : g_emu_thread->getInputDeviceListModel()->getDeviceList())
|
||||||
{
|
{
|
||||||
// we set it as data, because the device list could get invalidated while the menu is up
|
// we set it as data, because the device list could get invalidated while the menu is up
|
||||||
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(identifier).arg(device_name));
|
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.identifier).arg(dev.display_name));
|
||||||
action->setData(identifier);
|
action->setIcon(InputDeviceListModel::getIconForKey(dev.key));
|
||||||
|
action->setData(dev.identifier);
|
||||||
connect(action, &QAction::triggered, this, [this, port, update_label, action]() {
|
connect(action, &QAction::triggered, this, [this, port, update_label, action]() {
|
||||||
doDeviceAutomaticBinding(port, update_label, action->data().toString());
|
doDeviceAutomaticBinding(port, update_label, action->data().toString());
|
||||||
});
|
});
|
||||||
|
@ -2000,8 +2000,8 @@ InputManager::DeviceList InputManager::EnumerateDevices()
|
|||||||
InputBindingKey mouse_key = {};
|
InputBindingKey mouse_key = {};
|
||||||
mouse_key.source_type = InputSourceType::Pointer;
|
mouse_key.source_type = InputSourceType::Pointer;
|
||||||
|
|
||||||
ret.emplace_back(keyboard_key, "Keyboard", "Keyboard");
|
ret.emplace_back(keyboard_key, "Keyboard", TRANSLATE_STR("InputManager", "Keyboard"));
|
||||||
ret.emplace_back(mouse_key, "Mouse", "Mouse");
|
ret.emplace_back(mouse_key, GetPointerDeviceName(0), TRANSLATE_STR("InputManager", "Mouse"));
|
||||||
|
|
||||||
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user