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
This commit is contained in:
Megamouse 2017-06-16 19:43:22 +02:00 committed by Ivan
commit aca5c73fb3
3 changed files with 100 additions and 52 deletions

View file

@ -34,6 +34,8 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_
m_Text_Factor = xgui_settings->GetValue(GUI::gl_textFactor).toReal(); m_Text_Factor = xgui_settings->GetValue(GUI::gl_textFactor).toReal();
m_showToolBar = xgui_settings->GetValue(GUI::gl_toolBarVisible).toBool(); m_showToolBar = xgui_settings->GetValue(GUI::gl_toolBarVisible).toBool();
m_oldLayoutIsList = m_isListLayout;
// get icon size from list // get icon size from list
int icon_size_index = 0; int icon_size_index = 0;
for (int i = 0; i < GUI::gl_icon_size.count(); i++) for (int i = 0; i < GUI::gl_icon_size.count(); i++)
@ -141,7 +143,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_
setWidget(m_Game_Dock); setWidget(m_Game_Dock);
bool showText = (m_Icon_Size_Str != GUI::gl_icon_key_small && m_Icon_Size_Str != GUI::gl_icon_key_tiny); 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 = new QTableWidget();
gameList->setShowGrid(false); gameList->setShowGrid(false);
@ -156,7 +158,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_
gameList->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); gameList->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
gameList->setContextMenuPolicy(Qt::CustomContextMenu); gameList->setContextMenuPolicy(Qt::CustomContextMenu);
gameList->setColumnCount(8); gameList->setColumnCount(7);
gameList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Icon"))); gameList->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Icon")));
gameList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Name"))); gameList->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Name")));
gameList->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Serial"))); gameList->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Serial")));
@ -164,14 +166,11 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_
gameList->setHorizontalHeaderItem(4, new QTableWidgetItem(tr("App version"))); gameList->setHorizontalHeaderItem(4, new QTableWidgetItem(tr("App version")));
gameList->setHorizontalHeaderItem(5, new QTableWidgetItem(tr("Category"))); gameList->setHorizontalHeaderItem(5, new QTableWidgetItem(tr("Category")));
gameList->setHorizontalHeaderItem(6, new QTableWidgetItem(tr("Path"))); 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 = new QStackedWidget(this);
m_Central_Widget->addWidget(gameList); m_Central_Widget->addWidget(gameList);
m_Central_Widget->addWidget(m_xgrid.get()); m_Central_Widget->addWidget(m_xgrid);
m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid.get()); m_Central_Widget->setCurrentWidget(m_isListLayout ? gameList : m_xgrid);
m_Game_Dock->setCentralWidget(m_Central_Widget); m_Game_Dock->setCentralWidget(m_Central_Widget);
@ -196,8 +195,8 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, Render_
connect(gameList, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(gameList, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked); connect(gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
connect(m_xgrid.get(), &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid.get(), &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
connect(m_Slider_Size, &QSlider::valueChanged, [=](int value) { emit RequestIconSizeActSet(value); }); 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) if (m_isListLayout)
{ {
int row = gameList->currentRow(); int row = PopulateGameList();
PopulateGameList();
FilterData(); FilterData();
gameList->selectRow(row); gameList->selectRow(row);
gameList->sortByColumn(m_sortColumn, m_colSortOrder); gameList->sortByColumn(m_sortColumn, m_colSortOrder);
gameList->setColumnHidden(7, true);
gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height()); gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height());
gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height()); gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height());
gameList->resizeRowsToContents(); gameList->resizeRowsToContents();
gameList->resizeColumnToContents(0); gameList->resizeColumnToContents(0);
gameList->scrollTo(gameList->currentIndex());
} }
else else
{ {
if (m_Icon_Size.width() > 0 && m_Icon_Size.height() > 0) 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 else
{ {
m_games_per_row = 0; m_games_per_row = 0;
} }
m_xgrid.reset(MakeGrid(m_games_per_row, m_Icon_Size)); PopulateGameGrid(m_games_per_row, m_Icon_Size);
connect(m_xgrid.get(), &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid.get(), &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
m_Central_Widget->addWidget(m_xgrid.get()); m_Central_Widget->addWidget(m_xgrid);
m_Central_Widget->setCurrentWidget(m_xgrid.get()); 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) if (m_isListLayout)
{ {
i = gameList->item(index.row(), 7)->text().toInt(); i = gameList->item(index.row(), 0)->data(Qt::UserRole).toInt();
} }
else else
{ {
@ -533,9 +531,9 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
if (m_isListLayout) if (m_isListLayout)
{ {
int row = gameList->indexAt(pos).row(); 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. 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 else
{ {
@ -678,7 +676,7 @@ void game_list_frame::RemoveCustomConfiguration(int row)
void game_list_frame::ResizeIcons(const QSize& size, const int& idx) 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; m_Icon_Size_Str = GUI::gl_icon_size.at(idx).first;
xgui_settings->SetValue(GUI::gl_iconSize, m_Icon_Size_Str); 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) void game_list_frame::SetListMode(const bool& isList)
{ {
m_oldLayoutIsList = m_isListLayout;
m_isListLayout = isList; m_isListLayout = isList;
xgui_settings->SetValue(GUI::gl_listMode, isList); xgui_settings->SetValue(GUI::gl_listMode, isList);
@ -705,7 +704,7 @@ void game_list_frame::SetListMode(const bool& isList)
Refresh(); 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) 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. 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. // Hack to delete everything without removing the headers.
gameList->setRowCount(0); gameList->setRowCount(0);
@ -749,8 +752,7 @@ void game_list_frame::PopulateGameList()
{ {
QTableWidgetItem* curr = new QTableWidgetItem; QTableWidgetItem* curr = new QTableWidgetItem;
curr->setFlags(curr->flags() & ~Qt::ItemIsEditable); curr->setFlags(curr->flags() & ~Qt::ItemIsEditable);
QString qtext = qstr(text); curr->setText(qstr(text));
curr->setText(qtext);
return curr; return curr;
}; };
@ -768,6 +770,7 @@ void game_list_frame::PopulateGameList()
QTableWidgetItem* iconItem = new QTableWidgetItem; QTableWidgetItem* iconItem = new QTableWidgetItem;
iconItem->setFlags(iconItem->flags() & ~Qt::ItemIsEditable); iconItem->setFlags(iconItem->flags() & ~Qt::ItemIsEditable);
iconItem->setData(Qt::DecorationRole, game.pxmap); iconItem->setData(Qt::DecorationRole, game.pxmap);
iconItem->setData(Qt::UserRole, row);
gameList->setItem(row, 0, iconItem); gameList->setItem(row, 0, iconItem);
gameList->setItem(row, 1, l_GetItem(game.info.name)); 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, 5, l_GetItem(game.info.category));
gameList->setItem(row, 6, l_GetItem(game.info.root)); gameList->setItem(row, 6, l_GetItem(game.info.root));
// A certain magical index which points back to the original game index. if (selected_item == game.info.icon_path) result = row;
// 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);
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 r = 0;
uint c = 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; 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) 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 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. // 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! // Edge cases!
if (entries == 0) if (entries == 0)
{ // For whatever reason, 0%x is division by zero. Absolute nonsense by definition of modulus. But, I'll acquiesce. { // 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) 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 needsExtraRow = (entries % maxCols) != 0;
int maxRows = needsExtraRow + entries / maxCols; int maxRows = needsExtraRow + entries / maxCols;
grid->setRowCount(maxRows); m_xgrid->setRowCount(maxRows);
grid->setColumnCount(maxCols); m_xgrid->setColumnCount(maxCols);
for (uint i = 0; i < m_game_data.size(); i++) 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) 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) if (++c >= maxCols)
{ {
@ -866,14 +871,12 @@ game_list_grid* game_list_frame::MakeGrid(uint maxCols, const QSize& image_size)
QTableWidgetItem* emptyItem = new QTableWidgetItem(); QTableWidgetItem* emptyItem = new QTableWidgetItem();
emptyItem->setFlags(Qt::NoItemFlags); emptyItem->setFlags(Qt::NoItemFlags);
emptyItem->setData(Qt::UserRole, -1); emptyItem->setData(Qt::UserRole, -1);
grid->setItem(r, col, emptyItem); m_xgrid->setItem(r, col, emptyItem);
} }
} }
grid->resizeColumnsToContents(); m_xgrid->resizeColumnsToContents();
grid->resizeRowsToContents(); m_xgrid->resizeRowsToContents();
return grid;
} }
/** /**
@ -888,3 +891,21 @@ bool game_list_frame::SearchMatchesApp(const std::string& name, const std::strin
} }
return true; 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;
}

View file

@ -85,12 +85,14 @@ protected:
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
private: private:
game_list_grid* MakeGrid(uint maxCols, const QSize& image_size); void PopulateGameGrid(uint maxCols, const QSize& image_size);
void FilterData(); void FilterData();
void PopulateGameList(); int PopulateGameList();
bool SearchMatchesApp(const std::string& name, const std::string& serial); 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. // Which widget we are displaying depends on if we are in grid or list mode.
QMainWindow* m_Game_Dock; QMainWindow* m_Game_Dock;
QStackedWidget* m_Central_Widget; QStackedWidget* m_Central_Widget;
@ -98,7 +100,7 @@ private:
QLineEdit* m_Search_Bar; QLineEdit* m_Search_Bar;
QSlider* m_Slider_Size; QSlider* m_Slider_Size;
QTableWidget *gameList; QTableWidget *gameList;
std::unique_ptr<game_list_grid> m_xgrid; game_list_grid* m_xgrid;
// Actions regarding showing/hiding columns // Actions regarding showing/hiding columns
QAction* showIconColAct; QAction* showIconColAct;
@ -135,6 +137,7 @@ private:
int m_sortColumn; int m_sortColumn;
Qt::SortOrder m_colSortOrder; Qt::SortOrder m_colSortOrder;
bool m_isListLayout = true; bool m_isListLayout = true;
bool m_oldLayoutIsList = true;
bool m_showToolBar = true; bool m_showToolBar = true;
std::vector<GUI_GameInfo> m_game_data; std::vector<GUI_GameInfo> m_game_data;
QSize m_Icon_Size; QSize m_Icon_Size;

View file

@ -94,6 +94,11 @@ graphics_tab::graphics_tab(std::shared_ptr<emu_settings> xSettings, Render_Creat
// D3D Adapter // D3D Adapter
if (m_isD3D12) if (m_isD3D12)
{ {
// Reset other adapters to old config
if (supportsVulkan)
{
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan));
}
// Fill combobox // Fill combobox
graphicsAdapterBox->clear(); graphicsAdapterBox->clear();
for (auto adapter : D3D12Adapters) for (auto adapter : D3D12Adapters)
@ -101,19 +106,31 @@ graphics_tab::graphics_tab(std::shared_ptr<emu_settings> xSettings, Render_Creat
graphicsAdapterBox->addItem(adapter); graphicsAdapterBox->addItem(adapter);
} }
// Reset Adapter to old config // Reset Adapter to old config
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12));
int idx = graphicsAdapterBox->findText(old_D3D12); int idx = graphicsAdapterBox->findText(old_D3D12);
if (idx == -1) if (idx == -1)
{ {
idx = 0; 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); graphicsAdapterBox->setCurrentIndex(idx);
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(graphicsAdapterBox->currentText()));
} }
// Vulkan Adapter // Vulkan Adapter
else if (m_isVulkan) else if (m_isVulkan)
{ {
// Reset other adapters to old config
if (supportsD3D12)
{
xemu_settings->SetSetting(emu_settings::D3D12Adapter, sstr(old_D3D12));
}
// Fill combobox // Fill combobox
graphicsAdapterBox->clear(); graphicsAdapterBox->clear();
for (auto adapter : vulkanAdapters) for (auto adapter : vulkanAdapters)
@ -121,14 +138,21 @@ graphics_tab::graphics_tab(std::shared_ptr<emu_settings> xSettings, Render_Creat
graphicsAdapterBox->addItem(adapter); graphicsAdapterBox->addItem(adapter);
} }
// Reset Adapter to old config // Reset Adapter to old config
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(old_Vulkan));
int idx = graphicsAdapterBox->findText(old_Vulkan); int idx = graphicsAdapterBox->findText(old_Vulkan);
if (idx == -1) if (idx == -1)
{ {
idx = 0; 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); graphicsAdapterBox->setCurrentIndex(idx);
xemu_settings->SetSetting(emu_settings::VulkanAdapter, sstr(graphicsAdapterBox->currentText()));
} }
// Other Adapter // Other Adapter