From aca5c73fb3a87e26efa35e960ba605dcbd337a65 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 16 Jun 2017 19:43:22 +0200 Subject: [PATCH] Fix inconsistent selection in gamelist/grid (#2871) * use userrole instead of missingno * fix consistent gamelist selection * fix consistent gamegrid selection * scroll to selection on refresh * fix adapters not saved to config --- rpcs3/rpcs3qt/game_list_frame.cpp | 111 ++++++++++++++++++------------ rpcs3/rpcs3qt/game_list_frame.h | 9 ++- rpcs3/rpcs3qt/graphics_tab.cpp | 32 +++++++-- 3 files changed, 100 insertions(+), 52 deletions(-) diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 1d48476fb4..f7aa3b6091 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -34,6 +34,8 @@ game_list_frame::game_list_frame(std::shared_ptr settings, Render_ m_Text_Factor = xgui_settings->GetValue(GUI::gl_textFactor).toReal(); m_showToolBar = xgui_settings->GetValue(GUI::gl_toolBarVisible).toBool(); + m_oldLayoutIsList = m_isListLayout; + // get icon size from list int icon_size_index = 0; for (int i = 0; i < GUI::gl_icon_size.count(); i++) @@ -141,7 +143,7 @@ game_list_frame::game_list_frame(std::shared_ptr settings, Render_ setWidget(m_Game_Dock); bool showText = (m_Icon_Size_Str != GUI::gl_icon_key_small && m_Icon_Size_Str != GUI::gl_icon_key_tiny); - m_xgrid.reset(new game_list_grid(m_Icon_Size, m_Margin_Factor, m_Text_Factor, showText)); + m_xgrid = new game_list_grid(m_Icon_Size, m_Margin_Factor, m_Text_Factor, showText); gameList = new QTableWidget(); gameList->setShowGrid(false); @@ -156,7 +158,7 @@ game_list_frame::game_list_frame(std::shared_ptr settings, Render_ gameList->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); gameList->setContextMenuPolicy(Qt::CustomContextMenu); - gameList->setColumnCount(8); + gameList->setColumnCount(7); gameList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Icon"))); gameList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Name"))); gameList->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Serial"))); @@ -164,14 +166,11 @@ game_list_frame::game_list_frame(std::shared_ptr settings, Render_ gameList->setHorizontalHeaderItem(4, new QTableWidgetItem(tr("App version"))); gameList->setHorizontalHeaderItem(5, new QTableWidgetItem(tr("Category"))); gameList->setHorizontalHeaderItem(6, new QTableWidgetItem(tr("Path"))); - gameList->setHorizontalHeaderItem(7, new QTableWidgetItem(tr("Missingno"))); // Holds index which points back to original array - - gameList->setColumnHidden(7, true); // Comment this if your sorting ever for whatever reason messes up. m_Central_Widget = new QStackedWidget(this); m_Central_Widget->addWidget(gameList); - m_Central_Widget->addWidget(m_xgrid.get()); - m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid.get()); + m_Central_Widget->addWidget(m_xgrid); + m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid); m_Game_Dock->setCentralWidget(m_Central_Widget); @@ -196,8 +195,8 @@ game_list_frame::game_list_frame(std::shared_ptr settings, Render_ connect(gameList, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked); - connect(m_xgrid.get(), &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); - connect(m_xgrid.get(), &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); + connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); + connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); connect(m_Slider_Size, &QSlider::valueChanged, [=](int value) { emit RequestIconSizeActSet(value); }); @@ -421,34 +420,33 @@ void game_list_frame::Refresh(bool fromDrive) if (m_isListLayout) { - int row = gameList->currentRow(); - - PopulateGameList(); + int row = PopulateGameList(); FilterData(); gameList->selectRow(row); gameList->sortByColumn(m_sortColumn, m_colSortOrder); - gameList->setColumnHidden(7, true); gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height()); gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height()); gameList->resizeRowsToContents(); gameList->resizeColumnToContents(0); + gameList->scrollTo(gameList->currentIndex()); } else { if (m_Icon_Size.width() > 0 && m_Icon_Size.height() > 0) { - m_games_per_row = width() / (m_Icon_Size.width() + m_Icon_Size.width() * m_xgrid.get()->getMarginFactor() * 2); + m_games_per_row = width() / (m_Icon_Size.width() + m_Icon_Size.width() * m_xgrid->getMarginFactor() * 2); } else { m_games_per_row = 0; } - m_xgrid.reset(MakeGrid(m_games_per_row, m_Icon_Size)); - connect(m_xgrid.get(), &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); - connect(m_xgrid.get(), &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); - m_Central_Widget->addWidget(m_xgrid.get()); - m_Central_Widget->setCurrentWidget(m_xgrid.get()); + PopulateGameGrid(m_games_per_row, m_Icon_Size); + connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); + connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); + m_Central_Widget->addWidget(m_xgrid); + m_Central_Widget->setCurrentWidget(m_xgrid); + m_xgrid->scrollTo(m_xgrid->currentIndex()); } } @@ -493,7 +491,7 @@ void game_list_frame::doubleClickedSlot(const QModelIndex& index) if (m_isListLayout) { - i = gameList->item(index.row(), 7)->text().toInt(); + i = gameList->item(index.row(), 0)->data(Qt::UserRole).toInt(); } else { @@ -533,9 +531,9 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) if (m_isListLayout) { int row = gameList->indexAt(pos).row(); - QTableWidgetItem* item = gameList->item(row, 7); + QTableWidgetItem* item = gameList->item(row, 0); if (item == nullptr) return; // null happens if you are double clicking in dockwidget area on nothing. - index = item->text().toInt(); + index = item->data(Qt::UserRole).toInt(); } else { @@ -678,7 +676,7 @@ void game_list_frame::RemoveCustomConfiguration(int row) void game_list_frame::ResizeIcons(const QSize& size, const int& idx) { - m_Slider_Size->setSliderPosition(idx); + if (m_Slider_Size->value() != idx) m_Slider_Size->setSliderPosition(idx); m_Icon_Size_Str = GUI::gl_icon_size.at(idx).first; xgui_settings->SetValue(GUI::gl_iconSize, m_Icon_Size_Str); @@ -695,6 +693,7 @@ void game_list_frame::ResizeIcons(const QSize& size, const int& idx) void game_list_frame::SetListMode(const bool& isList) { + m_oldLayoutIsList = m_isListLayout; m_isListLayout = isList; xgui_settings->SetValue(GUI::gl_listMode, isList); @@ -705,7 +704,7 @@ void game_list_frame::SetListMode(const bool& isList) Refresh(); - m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid.get()); + m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid); } void game_list_frame::SetToolBarVisible(const bool& showToolBar) @@ -738,8 +737,12 @@ void game_list_frame::resizeEvent(QResizeEvent *event) /** Cleans and readds entries to table widget in UI. */ -void game_list_frame::PopulateGameList() +int game_list_frame::PopulateGameList() { + int result = -1; + + std::string selected_item = CurrentSelectionIconPath(); + // Hack to delete everything without removing the headers. gameList->setRowCount(0); @@ -749,8 +752,7 @@ void game_list_frame::PopulateGameList() { QTableWidgetItem* curr = new QTableWidgetItem; curr->setFlags(curr->flags() & ~Qt::ItemIsEditable); - QString qtext = qstr(text); - curr->setText(qtext); + curr->setText(qstr(text)); return curr; }; @@ -768,6 +770,7 @@ void game_list_frame::PopulateGameList() QTableWidgetItem* iconItem = new QTableWidgetItem; iconItem->setFlags(iconItem->flags() & ~Qt::ItemIsEditable); iconItem->setData(Qt::DecorationRole, game.pxmap); + iconItem->setData(Qt::UserRole, row); gameList->setItem(row, 0, iconItem); gameList->setItem(row, 1, l_GetItem(game.info.name)); @@ -777,32 +780,32 @@ void game_list_frame::PopulateGameList() gameList->setItem(row, 5, l_GetItem(game.info.category)); gameList->setItem(row, 6, l_GetItem(game.info.root)); - // A certain magical index which points back to the original game index. - // Essentially, this column makes the tablewidget's row into a map, accomplishing what columns did but much simpler. - QTableWidgetItem* index = new QTableWidgetItem; - index->setText(QString::number(row)); - gameList->setItem(row, 7, index); + if (selected_item == game.info.icon_path) result = row; row++; } + + return result; } -game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size) +void game_list_frame::PopulateGameGrid(uint maxCols, const QSize& image_size) { uint r = 0; uint c = 0; - game_list_grid* grid; + std::string selected_item = CurrentSelectionIconPath(); + + delete m_xgrid; bool showText = m_Icon_Size_Str != GUI::gl_icon_key_small && m_Icon_Size_Str != GUI::gl_icon_key_tiny; if (m_Icon_Size_Str == GUI::gl_icon_key_medium) { - grid = new game_list_grid(image_size, m_Margin_Factor, m_Text_Factor * 2, showText); + m_xgrid = new game_list_grid(image_size, m_Margin_Factor, m_Text_Factor * 2, showText); } else { - grid = new game_list_grid(image_size, m_Margin_Factor, m_Text_Factor, showText); + m_xgrid = new game_list_grid(image_size, m_Margin_Factor, m_Text_Factor, showText); } // Get number of things that'll be in grid and precompute grid size. @@ -822,7 +825,7 @@ game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size) // Edge cases! if (entries == 0) { // For whatever reason, 0%x is division by zero. Absolute nonsense by definition of modulus. But, I'll acquiesce. - return grid; + return; } if (maxCols == 0) { @@ -835,8 +838,8 @@ game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size) int needsExtraRow = (entries % maxCols) != 0; int maxRows = needsExtraRow + entries / maxCols; - grid->setRowCount(maxRows); - grid->setColumnCount(maxCols); + m_xgrid->setRowCount(maxRows); + m_xgrid->setColumnCount(maxCols); for (uint i = 0; i < m_game_data.size(); i++) { @@ -849,7 +852,9 @@ game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size) if (category == category::hdd_Game || category == category::disc_Game) { - grid->addItem(m_game_data[i].pxmap, qstr(m_game_data[i].info.name), i, r, c); + m_xgrid->addItem(m_game_data[i].pxmap, qstr(m_game_data[i].info.name), i, r, c); + + if (selected_item == m_game_data[i].info.icon_path) m_xgrid->setCurrentItem(m_xgrid->item(r, c));; if (++c >= maxCols) { @@ -866,14 +871,12 @@ game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size) QTableWidgetItem* emptyItem = new QTableWidgetItem(); emptyItem->setFlags(Qt::NoItemFlags); emptyItem->setData(Qt::UserRole, -1); - grid->setItem(r, col, emptyItem); + m_xgrid->setItem(r, col, emptyItem); } } - grid->resizeColumnsToContents(); - grid->resizeRowsToContents(); - - return grid; + m_xgrid->resizeColumnsToContents(); + m_xgrid->resizeRowsToContents(); } /** @@ -888,3 +891,21 @@ bool game_list_frame::SearchMatchesApp(const std::string& name, const std::strin } return true; } + +std::string game_list_frame::CurrentSelectionIconPath() +{ + std::string selection = ""; + + if (m_oldLayoutIsList && gameList->currentRow() >= 0) + { + selection = m_game_data.at(gameList->item(gameList->currentRow(), 0)->data(Qt::UserRole).toInt()).info.icon_path; + } + else if (!m_oldLayoutIsList && m_xgrid->currentItem() != nullptr) + { + selection = m_game_data.at(m_xgrid->currentItem()->data(Qt::UserRole).toInt()).info.icon_path; + } + + m_oldLayoutIsList = m_isListLayout; + + return selection; +} diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index f7feaf893c..10eb952e9d 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -85,12 +85,14 @@ protected: void closeEvent(QCloseEvent* event); void resizeEvent(QResizeEvent *event); private: - game_list_grid* MakeGrid(uint maxCols, const QSize& image_size); + void PopulateGameGrid(uint maxCols, const QSize& image_size); void FilterData(); - void PopulateGameList(); + int PopulateGameList(); bool SearchMatchesApp(const std::string& name, const std::string& serial); + std::string CurrentSelectionIconPath(); + // Which widget we are displaying depends on if we are in grid or list mode. QMainWindow* m_Game_Dock; QStackedWidget* m_Central_Widget; @@ -98,7 +100,7 @@ private: QLineEdit* m_Search_Bar; QSlider* m_Slider_Size; QTableWidget *gameList; - std::unique_ptr m_xgrid; + game_list_grid* m_xgrid; // Actions regarding showing/hiding columns QAction* showIconColAct; @@ -135,6 +137,7 @@ private: int m_sortColumn; Qt::SortOrder m_colSortOrder; bool m_isListLayout = true; + bool m_oldLayoutIsList = true; bool m_showToolBar = true; std::vector m_game_data; QSize m_Icon_Size; diff --git a/rpcs3/rpcs3qt/graphics_tab.cpp b/rpcs3/rpcs3qt/graphics_tab.cpp index eab4908aef..fb0483037d 100644 --- a/rpcs3/rpcs3qt/graphics_tab.cpp +++ b/rpcs3/rpcs3qt/graphics_tab.cpp @@ -94,6 +94,11 @@ graphics_tab::graphics_tab(std::shared_ptr xSettings, Render_Creat // D3D Adapter if (m_isD3D12) { + // Reset other adapters to old config + if (supportsVulkan) + { + xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan)); + } // Fill combobox graphicsAdapterBox->clear(); for (auto adapter : D3D12Adapters) @@ -101,19 +106,31 @@ graphics_tab::graphics_tab(std::shared_ptr xSettings, Render_Creat graphicsAdapterBox->addItem(adapter); } // Reset Adapter to old config - xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12)); int idx = graphicsAdapterBox->findText(old_D3D12); if (idx == -1) { idx = 0; - LOG_WARNING(RSX, "Current %s adapter not available: resetting to default!", sstr(r_D3D12)); + if (old_D3D12.isEmpty()) + { + LOG_WARNING(RSX, "%s adapter config empty: setting to default!", sstr(r_D3D12)); + } + else + { + LOG_WARNING(RSX, "Last used %s adapter not found: setting to default!", sstr(r_D3D12)); + } } graphicsAdapterBox->setCurrentIndex(idx); + xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(graphicsAdapterBox->currentText())); } // Vulkan Adapter else if (m_isVulkan) { + // Reset other adapters to old config + if (supportsD3D12) + { + xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12)); + } // Fill combobox graphicsAdapterBox->clear(); for (auto adapter : vulkanAdapters) @@ -121,14 +138,21 @@ graphics_tab::graphics_tab(std::shared_ptr xSettings, Render_Creat graphicsAdapterBox->addItem(adapter); } // Reset Adapter to old config - xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan)); int idx = graphicsAdapterBox->findText(old_Vulkan); if (idx == -1) { idx = 0; - LOG_WARNING(RSX, "Current %s adapter not available: resetting to default!", sstr(r_Vulkan)); + if (old_Vulkan.isEmpty()) + { + LOG_WARNING(RSX, "%s adapter config empty: setting to default!", sstr(r_Vulkan)); + } + else + { + LOG_WARNING(RSX, "Last used %s adapter not found: setting to default!", sstr(r_Vulkan)); + } } graphicsAdapterBox->setCurrentIndex(idx); + xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(graphicsAdapterBox->currentText())); } // Other Adapter