diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuzu/game_list.cpp | 80 | ||||
| -rw-r--r-- | src/yuzu/game_list.h | 24 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 15 |
3 files changed, 67 insertions, 52 deletions
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 6a71d9644..a9738e298 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -56,7 +56,7 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve | |||
| 56 | case Qt::Key_Return: | 56 | case Qt::Key_Return: |
| 57 | case Qt::Key_Enter: { | 57 | case Qt::Key_Enter: { |
| 58 | if (gamelist->search_field->visible == 1) { | 58 | if (gamelist->search_field->visible == 1) { |
| 59 | QString file_path = gamelist->getLastFilterResultItem(); | 59 | const QString file_path = gamelist->GetLastFilterResultItem(); |
| 60 | 60 | ||
| 61 | // To avoid loading error dialog loops while confirming them using enter | 61 | // To avoid loading error dialog loops while confirming them using enter |
| 62 | // Also users usually want to run a different game after closing one | 62 | // Also users usually want to run a different game after closing one |
| @@ -83,22 +83,25 @@ void GameListSearchField::setFilterResult(int visible, int total) { | |||
| 83 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); | 83 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | QString GameList::getLastFilterResultItem() const { | 86 | QString GameList::GetLastFilterResultItem() const { |
| 87 | QStandardItem* folder; | ||
| 88 | QStandardItem* child; | ||
| 89 | QString file_path; | 87 | QString file_path; |
| 90 | const int folder_count = item_model->rowCount(); | 88 | const int folder_count = item_model->rowCount(); |
| 89 | |||
| 91 | for (int i = 0; i < folder_count; ++i) { | 90 | for (int i = 0; i < folder_count; ++i) { |
| 92 | folder = item_model->item(i, 0); | 91 | const QStandardItem* folder = item_model->item(i, 0); |
| 93 | const QModelIndex folder_index = folder->index(); | 92 | const QModelIndex folder_index = folder->index(); |
| 94 | const int children_count = folder->rowCount(); | 93 | const int children_count = folder->rowCount(); |
| 94 | |||
| 95 | for (int j = 0; j < children_count; ++j) { | 95 | for (int j = 0; j < children_count; ++j) { |
| 96 | if (!tree_view->isRowHidden(j, folder_index)) { | 96 | if (tree_view->isRowHidden(j, folder_index)) { |
| 97 | child = folder->child(j, 0); | 97 | continue; |
| 98 | file_path = child->data(GameListItemPath::FullPathRole).toString(); | ||
| 99 | } | 98 | } |
| 99 | |||
| 100 | const QStandardItem* child = folder->child(j, 0); | ||
| 101 | file_path = child->data(GameListItemPath::FullPathRole).toString(); | ||
| 100 | } | 102 | } |
| 101 | } | 103 | } |
| 104 | |||
| 102 | return file_path; | 105 | return file_path; |
| 103 | } | 106 | } |
| 104 | 107 | ||
| @@ -123,7 +126,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { | |||
| 123 | edit_filter->setPlaceholderText(tr("Enter pattern to filter")); | 126 | edit_filter->setPlaceholderText(tr("Enter pattern to filter")); |
| 124 | edit_filter->installEventFilter(key_release_eater); | 127 | edit_filter->installEventFilter(key_release_eater); |
| 125 | edit_filter->setClearButtonEnabled(true); | 128 | edit_filter->setClearButtonEnabled(true); |
| 126 | connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged); | 129 | connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::OnTextChanged); |
| 127 | label_filter_result = new QLabel; | 130 | label_filter_result = new QLabel; |
| 128 | button_filter_close = new QToolButton(this); | 131 | button_filter_close = new QToolButton(this); |
| 129 | button_filter_close->setText(QStringLiteral("X")); | 132 | button_filter_close->setText(QStringLiteral("X")); |
| @@ -133,7 +136,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { | |||
| 133 | "#000000; font-weight: bold; background: #F0F0F0; }" | 136 | "#000000; font-weight: bold; background: #F0F0F0; }" |
| 134 | "QToolButton:hover{ border: none; padding: 0px; color: " | 137 | "QToolButton:hover{ border: none; padding: 0px; color: " |
| 135 | "#EEEEEE; font-weight: bold; background: #E81123}")); | 138 | "#EEEEEE; font-weight: bold; background: #E81123}")); |
| 136 | connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked); | 139 | connect(button_filter_close, &QToolButton::clicked, parent, &GameList::OnFilterCloseClicked); |
| 137 | layout_filter->setSpacing(10); | 140 | layout_filter->setSpacing(10); |
| 138 | layout_filter->addWidget(label_filter); | 141 | layout_filter->addWidget(label_filter); |
| 139 | layout_filter->addWidget(edit_filter); | 142 | layout_filter->addWidget(edit_filter); |
| @@ -159,16 +162,22 @@ static bool ContainsAllWords(const QString& haystack, const QString& userinput) | |||
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | // Syncs the expanded state of Game Directories with settings to persist across sessions | 164 | // Syncs the expanded state of Game Directories with settings to persist across sessions |
| 162 | void GameList::onItemExpanded(const QModelIndex& item) { | 165 | void GameList::OnItemExpanded(const QModelIndex& item) { |
| 163 | const auto type = item.data(GameListItem::TypeRole).value<GameListItemType>(); | 166 | const auto type = item.data(GameListItem::TypeRole).value<GameListItemType>(); |
| 164 | if (type == GameListItemType::CustomDir || type == GameListItemType::SdmcDir || | 167 | const bool is_dir = type == GameListItemType::CustomDir || type == GameListItemType::SdmcDir || |
| 165 | type == GameListItemType::UserNandDir || type == GameListItemType::SysNandDir) | 168 | type == GameListItemType::UserNandDir || |
| 166 | item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>()->expanded = | 169 | type == GameListItemType::SysNandDir; |
| 167 | tree_view->isExpanded(item); | 170 | |
| 171 | if (!is_dir) { | ||
| 172 | return; | ||
| 173 | } | ||
| 174 | |||
| 175 | auto* game_dir = item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); | ||
| 176 | game_dir->expanded = tree_view->isExpanded(item); | ||
| 168 | } | 177 | } |
| 169 | 178 | ||
| 170 | // Event in order to filter the gamelist after editing the searchfield | 179 | // Event in order to filter the gamelist after editing the searchfield |
| 171 | void GameList::onTextChanged(const QString& new_text) { | 180 | void GameList::OnTextChanged(const QString& new_text) { |
| 172 | const int folder_count = tree_view->model()->rowCount(); | 181 | const int folder_count = tree_view->model()->rowCount(); |
| 173 | QString edit_filter_text = new_text.toLower(); | 182 | QString edit_filter_text = new_text.toLower(); |
| 174 | QStandardItem* folder; | 183 | QStandardItem* folder; |
| @@ -224,7 +233,7 @@ void GameList::onTextChanged(const QString& new_text) { | |||
| 224 | } | 233 | } |
| 225 | } | 234 | } |
| 226 | 235 | ||
| 227 | void GameList::onUpdateThemedIcons() { | 236 | void GameList::OnUpdateThemedIcons() { |
| 228 | for (int i = 0; i < item_model->invisibleRootItem()->rowCount(); i++) { | 237 | for (int i = 0; i < item_model->invisibleRootItem()->rowCount(); i++) { |
| 229 | QStandardItem* child = item_model->invisibleRootItem()->child(i); | 238 | QStandardItem* child = item_model->invisibleRootItem()->child(i); |
| 230 | 239 | ||
| @@ -276,7 +285,7 @@ void GameList::onUpdateThemedIcons() { | |||
| 276 | } | 285 | } |
| 277 | } | 286 | } |
| 278 | 287 | ||
| 279 | void GameList::onFilterCloseClicked() { | 288 | void GameList::OnFilterCloseClicked() { |
| 280 | main_window->filterBarSetChecked(false); | 289 | main_window->filterBarSetChecked(false); |
| 281 | } | 290 | } |
| 282 | 291 | ||
| @@ -317,11 +326,11 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvide | |||
| 317 | } | 326 | } |
| 318 | item_model->setSortRole(GameListItemPath::SortRole); | 327 | item_model->setSortRole(GameListItemPath::SortRole); |
| 319 | 328 | ||
| 320 | connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::onUpdateThemedIcons); | 329 | connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons); |
| 321 | connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); | 330 | connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); |
| 322 | connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu); | 331 | connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu); |
| 323 | connect(tree_view, &QTreeView::expanded, this, &GameList::onItemExpanded); | 332 | connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded); |
| 324 | connect(tree_view, &QTreeView::collapsed, this, &GameList::onItemExpanded); | 333 | connect(tree_view, &QTreeView::collapsed, this, &GameList::OnItemExpanded); |
| 325 | 334 | ||
| 326 | // We must register all custom types with the Qt Automoc system so that we are able to use | 335 | // We must register all custom types with the Qt Automoc system so that we are able to use |
| 327 | // it with signals/slots. In this case, QList falls under the umbrells of custom types. | 336 | // it with signals/slots. In this case, QList falls under the umbrells of custom types. |
| @@ -338,17 +347,17 @@ GameList::~GameList() { | |||
| 338 | emit ShouldCancelWorker(); | 347 | emit ShouldCancelWorker(); |
| 339 | } | 348 | } |
| 340 | 349 | ||
| 341 | void GameList::setFilterFocus() { | 350 | void GameList::SetFilterFocus() { |
| 342 | if (tree_view->model()->rowCount() > 0) { | 351 | if (tree_view->model()->rowCount() > 0) { |
| 343 | search_field->setFocus(); | 352 | search_field->setFocus(); |
| 344 | } | 353 | } |
| 345 | } | 354 | } |
| 346 | 355 | ||
| 347 | void GameList::setFilterVisible(bool visibility) { | 356 | void GameList::SetFilterVisible(bool visibility) { |
| 348 | search_field->setVisible(visibility); | 357 | search_field->setVisible(visibility); |
| 349 | } | 358 | } |
| 350 | 359 | ||
| 351 | void GameList::clearFilter() { | 360 | void GameList::ClearFilter() { |
| 352 | search_field->clear(); | 361 | search_field->clear(); |
| 353 | } | 362 | } |
| 354 | 363 | ||
| @@ -397,10 +406,11 @@ void GameList::ValidateEntry(const QModelIndex& item) { | |||
| 397 | } | 406 | } |
| 398 | } | 407 | } |
| 399 | 408 | ||
| 400 | bool GameList::isEmpty() const { | 409 | bool GameList::IsEmpty() const { |
| 401 | for (int i = 0; i < item_model->rowCount(); i++) { | 410 | for (int i = 0; i < item_model->rowCount(); i++) { |
| 402 | const QStandardItem* child = item_model->invisibleRootItem()->child(i); | 411 | const QStandardItem* child = item_model->invisibleRootItem()->child(i); |
| 403 | const auto type = static_cast<GameListItemType>(child->type()); | 412 | const auto type = static_cast<GameListItemType>(child->type()); |
| 413 | |||
| 404 | if (!child->hasChildren() && | 414 | if (!child->hasChildren() && |
| 405 | (type == GameListItemType::SdmcDir || type == GameListItemType::UserNandDir || | 415 | (type == GameListItemType::SdmcDir || type == GameListItemType::UserNandDir || |
| 406 | type == GameListItemType::SysNandDir)) { | 416 | type == GameListItemType::SysNandDir)) { |
| @@ -408,11 +418,12 @@ bool GameList::isEmpty() const { | |||
| 408 | i--; | 418 | i--; |
| 409 | } | 419 | } |
| 410 | } | 420 | } |
| 421 | |||
| 411 | return !item_model->invisibleRootItem()->hasChildren(); | 422 | return !item_model->invisibleRootItem()->hasChildren(); |
| 412 | } | 423 | } |
| 413 | 424 | ||
| 414 | void GameList::DonePopulating(QStringList watch_list) { | 425 | void GameList::DonePopulating(const QStringList& watch_list) { |
| 415 | emit ShowList(!isEmpty()); | 426 | emit ShowList(!IsEmpty()); |
| 416 | 427 | ||
| 417 | item_model->invisibleRootItem()->appendRow(new GameListAddDir()); | 428 | item_model->invisibleRootItem()->appendRow(new GameListAddDir()); |
| 418 | 429 | ||
| @@ -472,7 +483,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { | |||
| 472 | context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location)); | 483 | context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location)); |
| 473 | } | 484 | } |
| 474 | 485 | ||
| 475 | void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string path) { | 486 | void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) { |
| 476 | QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); | 487 | QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); |
| 477 | QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location")); | 488 | QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location")); |
| 478 | QAction* open_transferable_shader_cache = | 489 | QAction* open_transferable_shader_cache = |
| @@ -690,12 +701,15 @@ void GameList::SaveInterfaceLayout() { | |||
| 690 | } | 701 | } |
| 691 | 702 | ||
| 692 | void GameList::LoadInterfaceLayout() { | 703 | void GameList::LoadInterfaceLayout() { |
| 693 | auto header = tree_view->header(); | 704 | auto* header = tree_view->header(); |
| 694 | if (!header->restoreState(UISettings::values.gamelist_header_state)) { | 705 | |
| 695 | // We are using the name column to display icons and titles | 706 | if (header->restoreState(UISettings::values.gamelist_header_state)) { |
| 696 | // so make it as large as possible as default. | 707 | return; |
| 697 | header->resizeSection(COLUMN_NAME, header->width()); | ||
| 698 | } | 708 | } |
| 709 | |||
| 710 | // We are using the name column to display icons and titles | ||
| 711 | // so make it as large as possible as default. | ||
| 712 | header->resizeSection(COLUMN_NAME, header->width()); | ||
| 699 | } | 713 | } |
| 700 | 714 | ||
| 701 | const QStringList GameList::supported_file_extensions = { | 715 | const QStringList GameList::supported_file_extensions = { |
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 78e2ba169..58059a3c4 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -67,11 +67,11 @@ public: | |||
| 67 | FileSys::ManualContentProvider* provider, GMainWindow* parent = nullptr); | 67 | FileSys::ManualContentProvider* provider, GMainWindow* parent = nullptr); |
| 68 | ~GameList() override; | 68 | ~GameList() override; |
| 69 | 69 | ||
| 70 | QString getLastFilterResultItem() const; | 70 | QString GetLastFilterResultItem() const; |
| 71 | void clearFilter(); | 71 | void ClearFilter(); |
| 72 | void setFilterFocus(); | 72 | void SetFilterFocus(); |
| 73 | void setFilterVisible(bool visibility); | 73 | void SetFilterVisible(bool visibility); |
| 74 | bool isEmpty() const; | 74 | bool IsEmpty() const; |
| 75 | 75 | ||
| 76 | void LoadCompatibilityList(); | 76 | void LoadCompatibilityList(); |
| 77 | void PopulateAsync(QVector<UISettings::GameDir>& game_dirs); | 77 | void PopulateAsync(QVector<UISettings::GameDir>& game_dirs); |
| @@ -82,7 +82,7 @@ public: | |||
| 82 | static const QStringList supported_file_extensions; | 82 | static const QStringList supported_file_extensions; |
| 83 | 83 | ||
| 84 | signals: | 84 | signals: |
| 85 | void GameChosen(QString game_path); | 85 | void GameChosen(const QString& game_path); |
| 86 | void ShouldCancelWorker(); | 86 | void ShouldCancelWorker(); |
| 87 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target, | 87 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target, |
| 88 | const std::string& game_path); | 88 | const std::string& game_path); |
| @@ -99,21 +99,21 @@ signals: | |||
| 99 | void ShowList(bool show); | 99 | void ShowList(bool show); |
| 100 | 100 | ||
| 101 | private slots: | 101 | private slots: |
| 102 | void onItemExpanded(const QModelIndex& item); | 102 | void OnItemExpanded(const QModelIndex& item); |
| 103 | void onTextChanged(const QString& new_text); | 103 | void OnTextChanged(const QString& new_text); |
| 104 | void onFilterCloseClicked(); | 104 | void OnFilterCloseClicked(); |
| 105 | void onUpdateThemedIcons(); | 105 | void OnUpdateThemedIcons(); |
| 106 | 106 | ||
| 107 | private: | 107 | private: |
| 108 | void AddDirEntry(GameListDir* entry_items); | 108 | void AddDirEntry(GameListDir* entry_items); |
| 109 | void AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent); | 109 | void AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent); |
| 110 | void ValidateEntry(const QModelIndex& item); | 110 | void ValidateEntry(const QModelIndex& item); |
| 111 | void DonePopulating(QStringList watch_list); | 111 | void DonePopulating(const QStringList& watch_list); |
| 112 | 112 | ||
| 113 | void RefreshGameDirectory(); | 113 | void RefreshGameDirectory(); |
| 114 | 114 | ||
| 115 | void PopupContextMenu(const QPoint& menu_location); | 115 | void PopupContextMenu(const QPoint& menu_location); |
| 116 | void AddGamePopup(QMenu& context_menu, u64 program_id, std::string path); | 116 | void AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path); |
| 117 | void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected); | 117 | void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected); |
| 118 | void AddPermDirPopup(QMenu& context_menu, QModelIndex selected); | 118 | void AddPermDirPopup(QMenu& context_menu, QModelIndex selected); |
| 119 | 119 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index bb3a08ac7..6a2a88dd8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -838,7 +838,7 @@ void GMainWindow::RestoreUIState() { | |||
| 838 | OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked()); | 838 | OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked()); |
| 839 | 839 | ||
| 840 | ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar); | 840 | ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar); |
| 841 | game_list->setFilterVisible(ui.action_Show_Filter_Bar->isChecked()); | 841 | game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); |
| 842 | 842 | ||
| 843 | ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar); | 843 | ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar); |
| 844 | statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); | 844 | statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); |
| @@ -1199,11 +1199,12 @@ void GMainWindow::ShutdownGame() { | |||
| 1199 | render_window->hide(); | 1199 | render_window->hide(); |
| 1200 | loading_screen->hide(); | 1200 | loading_screen->hide(); |
| 1201 | loading_screen->Clear(); | 1201 | loading_screen->Clear(); |
| 1202 | if (game_list->isEmpty()) | 1202 | if (game_list->IsEmpty()) { |
| 1203 | game_list_placeholder->show(); | 1203 | game_list_placeholder->show(); |
| 1204 | else | 1204 | } else { |
| 1205 | game_list->show(); | 1205 | game_list->show(); |
| 1206 | game_list->setFilterFocus(); | 1206 | } |
| 1207 | game_list->SetFilterFocus(); | ||
| 1207 | 1208 | ||
| 1208 | setMouseTracking(false); | 1209 | setMouseTracking(false); |
| 1209 | ui.centralwidget->setMouseTracking(false); | 1210 | ui.centralwidget->setMouseTracking(false); |
| @@ -2361,11 +2362,11 @@ void GMainWindow::OnAbout() { | |||
| 2361 | } | 2362 | } |
| 2362 | 2363 | ||
| 2363 | void GMainWindow::OnToggleFilterBar() { | 2364 | void GMainWindow::OnToggleFilterBar() { |
| 2364 | game_list->setFilterVisible(ui.action_Show_Filter_Bar->isChecked()); | 2365 | game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); |
| 2365 | if (ui.action_Show_Filter_Bar->isChecked()) { | 2366 | if (ui.action_Show_Filter_Bar->isChecked()) { |
| 2366 | game_list->setFilterFocus(); | 2367 | game_list->SetFilterFocus(); |
| 2367 | } else { | 2368 | } else { |
| 2368 | game_list->clearFilter(); | 2369 | game_list->ClearFilter(); |
| 2369 | } | 2370 | } |
| 2370 | } | 2371 | } |
| 2371 | 2372 | ||