Browse Source

feat: Changed folders in list to be a toggleable option

Akatsuki Levi 2 years ago
parent
commit
8b6a4c21f3
7 changed files with 105 additions and 22 deletions
  1. 48 13
      src/suyu/game_list.cpp
  2. 1 0
      src/suyu/game_list.h
  3. 31 9
      src/suyu/game_list_worker.cpp
  4. 11 0
      src/suyu/main.cpp
  5. 1 0
      src/suyu/main.h
  6. 12 0
      src/suyu/main.ui
  7. 1 0
      src/suyu/uisettings.h

+ 48 - 13
src/suyu/game_list.cpp

@@ -383,6 +383,17 @@ GameList::~GameList() {
     UnloadController();
 }
 
+void GameList::ClearList() {
+    // Clear all items
+    item_model->setRowCount(0);
+
+    // Notify a reload is pending
+    UISettings::values.is_game_list_reload_pending.exchange(true);
+    UISettings::values.is_game_list_reload_pending.notify_all();
+
+    // Load stuff back up
+}
+
 void GameList::SetFilterFocus() {
     if (tree_view->model()->rowCount() > 0) {
         search_field->setFocus();
@@ -471,7 +482,9 @@ bool GameList::IsEmpty() const {
 void GameList::DonePopulating(const QStringList& watch_list) {
     emit ShowList(!IsEmpty());
 
-    // item_model->invisibleRootItem()->appendRow(new GameListAddDir());
+    if (UISettings::values.show_folders_in_list) {
+        item_model->invisibleRootItem()->appendRow(new GameListAddDir());
+    }
 
     // Add favorites row
     item_model->invisibleRootItem()->insertRow(0, new GameListFavorites());
@@ -889,22 +902,44 @@ void GameList::ToggleFavorite(u64 program_id) {
 void GameList::AddFavorite(u64 program_id) {
     auto* favorites_row = item_model->item(0);
 
-    for (int i = 1; i < item_model->rowCount() - 1; i++) {
-        const auto* game = item_model->item(i);
-        if (game->data(GameListItemPath::ProgramIdRole).toULongLong() != program_id) {
-            continue;
+    if (UISettings::values.show_folders_in_list) {
+        for (int i = 0; i < item_model->rowCount(); i++) {
+            const auto* folder = item_model->item(i);
+            for (int j = 0; j < folder->rowCount(); j++) {
+                if (folder->child(j)->data(GameListItemPath::ProgramIdRole).toULongLong() ==
+                    program_id) {
+                    QList<QStandardItem*> list;
+                    for (int k = 0; k < COLUMN_COUNT; k++) {
+                        list.append(folder->child(j, k)->clone());
+                    }
+                    list[0]->setData(folder->child(j)->data(GameListItem::SortRole),
+                                     GameListItem::SortRole);
+                    list[0]->setText(folder->child(j)->data(Qt::DisplayRole).toString());
+
+                    favorites_row->appendRow(list);
+                    return;
+                }
+            }
         }
+        return;
+    } else {
+        for (int i = 1; i < item_model->rowCount() - 1; i++) {
+            const auto* game = item_model->item(i);
+            if (game->data(GameListItemPath::ProgramIdRole).toULongLong() != program_id) {
+                continue;
+            }
 
-        QList<QStandardItem*> list;
-        for (int j = 0; j < COLUMN_COUNT; j++) {
-            list.append(item_model->item(i, j)->clone());
-        }
+            QList<QStandardItem*> list;
+            for (int j = 0; j < COLUMN_COUNT; j++) {
+                list.append(item_model->item(i, j)->clone());
+            }
 
-        list[0]->setData(game->data(GameListItem::SortRole), GameListItem::SortRole);
-        list[0]->setText(game->data(Qt::DisplayRole).toString());
+            list[0]->setData(game->data(GameListItem::SortRole), GameListItem::SortRole);
+            list[0]->setText(game->data(Qt::DisplayRole).toString());
 
-        favorites_row->appendRow(list);
-        return;
+            favorites_row->appendRow(list);
+            return;
+        }
     }
 }
 

+ 1 - 0
src/suyu/game_list.h

@@ -84,6 +84,7 @@ public:
     ~GameList() override;
 
     QString GetLastFilterResultItem() const;
+    void ClearList();
     void ClearFilter();
     void SetFilterFocus();
     void SetFilterVisible(bool visibility);

+ 31 - 9
src/suyu/game_list_worker.cpp

@@ -330,13 +330,19 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
 
         auto entry = MakeGameListEntry(file->GetFullPath(), name, file->GetSize(), icon, *loader,
                                        program_id, compatibility_list, play_time_manager, patch);
-        RecordEvent([=](GameList* game_list) { game_list->AddRootEntry(entry); });
+        RecordEvent([=](GameList* game_list) {
+            if (UISettings::values.show_folders_in_list) {
+                game_list->AddEntry(entry, parent_dir);
+            } else {
+                game_list->AddRootEntry(entry);
+            }
+        });
     }
 }
 
 void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path, bool deep_scan,
                                     GameListDir* parent_dir) {
-    const auto callback = [this, target](const std::filesystem::path& path) -> bool {
+    const auto callback = [this, target, parent_dir](const std::filesystem::path& path) -> bool {
         if (stop_requested) {
             // Breaks the callback loop.
             return false;
@@ -424,7 +430,13 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
                         physical_name, name, Common::FS::GetSize(physical_name), icon, *loader,
                         program_id, compatibility_list, play_time_manager, patch);
 
-                    RecordEvent([=](GameList* game_list) { game_list->AddRootEntry(entry); });
+                    RecordEvent([=](GameList* game_list) {
+                        if (UISettings::values.show_folders_in_list) {
+                            game_list->AddEntry(entry, parent_dir);
+                        } else {
+                            game_list->AddRootEntry(entry);
+                        }
+                    });
                 }
             }
         } else if (is_dir) {
@@ -446,11 +458,9 @@ void GameListWorker::run() {
     watch_list.clear();
     provider->ClearAllEntries();
 
-    /*
     const auto DirEntryReady = [&](GameListDir* game_list_dir) {
         RecordEvent([=](GameList* game_list) { game_list->AddDirEntry(game_list_dir); });
     };
-    */
 
     for (UISettings::GameDir& game_dir : game_dirs) {
         if (stop_requested) {
@@ -459,20 +469,32 @@ void GameListWorker::run() {
 
         if (game_dir.path == std::string("SDMC")) {
             auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SdmcDir);
-            // DirEntryReady(game_list_dir);
+
+            if (UISettings::values.show_folders_in_list)
+                DirEntryReady(game_list_dir);
+
             AddTitlesToGameList(game_list_dir);
         } else if (game_dir.path == std::string("UserNAND")) {
             auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::UserNandDir);
-            // DirEntryReady(game_list_dir);
+
+            if (UISettings::values.show_folders_in_list)
+                DirEntryReady(game_list_dir);
+
             AddTitlesToGameList(game_list_dir);
         } else if (game_dir.path == std::string("SysNAND")) {
             auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SysNandDir);
-            // DirEntryReady(game_list_dir);
+
+            if (UISettings::values.show_folders_in_list)
+                DirEntryReady(game_list_dir);
+
             AddTitlesToGameList(game_list_dir);
         } else {
             watch_list.append(QString::fromStdString(game_dir.path));
             auto* const game_list_dir = new GameListDir(game_dir);
-            // DirEntryReady(game_list_dir);
+
+            if (UISettings::values.show_folders_in_list)
+                DirEntryReady(game_list_dir);
+
             ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path, game_dir.deep_scan,
                            game_list_dir);
             ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path, game_dir.deep_scan,

+ 11 - 0
src/suyu/main.cpp

@@ -1416,6 +1416,7 @@ void GMainWindow::RestoreUIState() {
     game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
 
     ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue());
+    ui->action_Show_Folders_In_List->setChecked(UISettings::values.show_folders_in_list.GetValue());
     statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
     Debugger::ToggleConsole();
 }
@@ -1531,6 +1532,7 @@ void GMainWindow::ConnectMenuEvents() {
     connect_menu(ui->action_Display_Dock_Widget_Headers, &GMainWindow::OnDisplayTitleBars);
     connect_menu(ui->action_Show_Filter_Bar, &GMainWindow::OnToggleFilterBar);
     connect_menu(ui->action_Show_Status_Bar, &GMainWindow::OnToggleStatusBar);
+    connect_menu(ui->action_Show_Folders_In_List, &GMainWindow::OnToggleFoldersInList);
 
     connect_menu(ui->action_Reset_Window_Size_720, &GMainWindow::ResetWindowSize720);
     connect_menu(ui->action_Reset_Window_Size_900, &GMainWindow::ResetWindowSize900);
@@ -4185,6 +4187,14 @@ void GMainWindow::OnToggleStatusBar() {
     statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
 }
 
+void GMainWindow::OnToggleFoldersInList() {
+    UISettings::values.show_folders_in_list = ui->action_Show_Folders_In_List->isChecked();
+
+    game_list->ClearList();
+    game_list->LoadCompatibilityList();
+    game_list->PopulateAsync(UISettings::values.game_dirs);
+}
+
 void GMainWindow::OnAlbum() {
     constexpr u64 AlbumId = static_cast<u64>(Service::AM::AppletProgramId::PhotoViewer);
     auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
@@ -4573,6 +4583,7 @@ void GMainWindow::UpdateUISettings() {
     UISettings::values.display_titlebar = ui->action_Display_Dock_Widget_Headers->isChecked();
     UISettings::values.show_filter_bar = ui->action_Show_Filter_Bar->isChecked();
     UISettings::values.show_status_bar = ui->action_Show_Status_Bar->isChecked();
+    UISettings::values.show_folders_in_list = ui->action_Show_Folders_In_List->isChecked();
     UISettings::values.first_start = false;
 }
 

+ 1 - 0
src/suyu/main.h

@@ -383,6 +383,7 @@ private slots:
     void OnAbout();
     void OnToggleFilterBar();
     void OnToggleStatusBar();
+    void OnToggleFoldersInList();
     void OnDisplayTitleBars(bool);
     void InitializeHotkeys();
     void ToggleFullscreen();

+ 12 - 0
src/suyu/main.ui

@@ -124,6 +124,7 @@
     <addaction name="action_Display_Dock_Widget_Headers"/>
     <addaction name="action_Show_Filter_Bar"/>
     <addaction name="action_Show_Status_Bar"/>
+    <addaction name="action_Show_Folders_In_List" />
     <addaction name="separator"/>
     <addaction name="menu_Reset_Window_Size"/>
     <addaction name="menu_View_Debugging"/>
@@ -288,6 +289,17 @@
     <string>Show Status Bar</string>
    </property>
   </action>
+  <action name="action_Show_Folders_In_List">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Show Folders in List</string>
+   </property>
+   <property name="iconText">
+    <string>Show Status Bar</string>
+   </property>
+  </action>
   <action name="action_View_Lobby">
    <property name="enabled">
     <bool>true</bool>

+ 1 - 0
src/suyu/uisettings.h

@@ -200,6 +200,7 @@ struct Values {
     std::atomic_bool is_game_list_reload_pending{false};
     Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
     Setting<bool> favorites_expanded{linkage, true, "favorites_expanded", Category::UiGameList};
+    Setting<bool> show_folders_in_list{linkage, true, "show_folders_in_list", Category::UiGameList};
     QVector<u64> favorited_ids;
 
     // Compatibility List