From a33612cf7d0dfde45d3b96d51e65c96ee919a93a Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:11:05 +0000 Subject: [PATCH] Qt: Display when the hovered cheat will be applied in the UI --- pcsx2-qt/Settings/GameCheatSettingsWidget.cpp | 64 +++++++++++++++++-- pcsx2-qt/Settings/GameCheatSettingsWidget.h | 8 +++ pcsx2-qt/Settings/GameCheatSettingsWidget.ui | 7 ++ 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/pcsx2-qt/Settings/GameCheatSettingsWidget.cpp b/pcsx2-qt/Settings/GameCheatSettingsWidget.cpp index a4608eb934..1d6c448da4 100644 --- a/pcsx2-qt/Settings/GameCheatSettingsWidget.cpp +++ b/pcsx2-qt/Settings/GameCheatSettingsWidget.cpp @@ -40,6 +40,9 @@ GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* settings_dialog m_ui.cheatList->expandAll(); + m_ui.cheatList->viewport()->installEventFilter(this); + m_ui.cheatList->viewport()->setMouseTracking(true); + SettingsInterface* sif = dialog()->getSettingsInterface(); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableCheats, "EmuCore", "EnableCheats", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.allCRCsCheckbox, "EmuCore", "ShowCheatsForAllCRCs", false); @@ -83,7 +86,7 @@ void GameCheatSettingsWidget::onCheatListItemDoubleClicked(const QModelIndex& in return; } - QVariant data = item->data(Qt::UserRole); + QVariant data = item->data(NAME_ROLE); if (!data.isValid()) return; @@ -95,7 +98,7 @@ void GameCheatSettingsWidget::onCheatListItemDoubleClicked(const QModelIndex& in void GameCheatSettingsWidget::onCheatListItemChanged(QStandardItem* item) { - QVariant data = item->data(Qt::UserRole); + QVariant data = item->data(NAME_ROLE); if (!data.isValid()) return; @@ -109,6 +112,31 @@ void GameCheatSettingsWidget::onCheatListItemChanged(QStandardItem* item) setCheatEnabled(std::move(cheat_name), current_checked, true); } +void GameCheatSettingsWidget::onCheatListItemHovered(const QModelIndex& index) +{ + const QModelIndex source_index = m_model_proxy->mapToSource(index); + const QModelIndex sibling_index = source_index.siblingAtColumn(0); + QStandardItem* item = m_model->itemFromIndex(sibling_index); + if (!item) + { + // No item is selected. + m_ui.appliedLabel->clear(); + return; + } + + std::optional place; + + bool ok; + int place_value = item->data(PLACE_ROLE).toInt(&ok); + if (ok) + { + // The patch commands in the group are all applied at the same time. + place = static_cast(place_value); + } + + m_ui.appliedLabel->setText(tr("Applied: %1").arg(Patch::PlaceToString(place))); +} + void GameCheatSettingsWidget::onReloadClicked() { reloadList(); @@ -136,6 +164,32 @@ void GameCheatSettingsWidget::disableAllCheats() si->Save(); } +bool GameCheatSettingsWidget::eventFilter(QObject* watched, QEvent* event) +{ + if (watched == m_ui.cheatList->viewport()) + { + switch (event->type()) + { + case QEvent::MouseMove: + { + QMouseEvent* mouse_event = static_cast(event); + onCheatListItemHovered(m_ui.cheatList->indexAt(mouse_event->position().toPoint())); + return true; + } + case QEvent::Leave: + { + onCheatListItemHovered(QModelIndex()); + return true; + } + default: + { + } + } + } + + return SettingsWidget::eventFilter(watched, event); +} + void GameCheatSettingsWidget::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); @@ -185,7 +239,7 @@ void GameCheatSettingsWidget::setStateRecursively(QStandardItem* parent, bool en for (int i = 0; i < count; i++) { QStandardItem* item = parent ? parent->child(i, 0) : m_model->item(i, 0); - QVariant data = item->data(Qt::UserRole); + QVariant data = item->data(NAME_ROLE); if (data.isValid()) { if ((item->checkState() == Qt::Checked) != enabled) @@ -277,7 +331,9 @@ QList GameCheatSettingsWidget::populateTreeViewRow(const Patch:: const std::string_view name_part = pi.GetNamePart(); nameItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren | Qt::ItemIsEnabled); nameItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); - nameItem->setData(QString::fromStdString(pi.name), Qt::UserRole); + nameItem->setData(QString::fromStdString(pi.name), NAME_ROLE); + if (pi.place.has_value()) + nameItem->setData(static_cast(*pi.place), PLACE_ROLE); if (!name_part.empty()) nameItem->setText(QString::fromUtf8(name_part.data(), name_part.length())); diff --git a/pcsx2-qt/Settings/GameCheatSettingsWidget.h b/pcsx2-qt/Settings/GameCheatSettingsWidget.h index e3b087baf5..bf4d03e010 100644 --- a/pcsx2-qt/Settings/GameCheatSettingsWidget.h +++ b/pcsx2-qt/Settings/GameCheatSettingsWidget.h @@ -32,6 +32,7 @@ public: ~GameCheatSettingsWidget(); void disableAllCheats(); + bool eventFilter(QObject* watched, QEvent* event) override; protected: void resizeEvent(QResizeEvent* event) override; @@ -39,6 +40,7 @@ protected: private Q_SLOTS: void onCheatListItemDoubleClicked(const QModelIndex& index); void onCheatListItemChanged(QStandardItem* item); + void onCheatListItemHovered(const QModelIndex& index); void onReloadClicked(); void updateListEnabled(); void reloadList(); @@ -50,6 +52,12 @@ private: void setStateForAll(bool enabled); void setStateRecursively(QStandardItem* parent, bool enabled); + enum Roles + { + NAME_ROLE = Qt::UserRole, + PLACE_ROLE = Qt::UserRole + 1 + }; + Ui::GameCheatSettingsWidget m_ui; QStandardItemModel* m_model = nullptr; QSortFilterProxyModel* m_model_proxy = nullptr; diff --git a/pcsx2-qt/Settings/GameCheatSettingsWidget.ui b/pcsx2-qt/Settings/GameCheatSettingsWidget.ui index 03d2fa9d7c..f34a35ebd9 100644 --- a/pcsx2-qt/Settings/GameCheatSettingsWidget.ui +++ b/pcsx2-qt/Settings/GameCheatSettingsWidget.ui @@ -90,6 +90,13 @@ + + + + + + +