Fixed multiple issues with filters and the gamelistInfo field.

This commit is contained in:
Leon Styhre 2020-11-09 23:41:27 +01:00
parent f17bf43d4f
commit db94f5daee
7 changed files with 51 additions and 61 deletions

View file

@ -53,26 +53,6 @@ void GuiGamelistFilter::initializeMenu()
void GuiGamelistFilter::resetAllFilters() void GuiGamelistFilter::resetAllFilters()
{ {
// For grouped custom collections, if the user locks himself out by applying a filter
// and then removes all entries that are applied by the filter, then this workaround is
// required to reset the filters. This situation may occur if filtering on favorite games,
// and then unflagging all games as favorites, ending up with the <NO ENTRIES FOUND>
// indicator. Without this code an application restart would have been required to
// reset the filters.
if (mSystem->isCollection() && mSystem->getFullName() == "collections") {
std::vector<FileData*> customCollections = mSystem->getRootFolder()->getChildren();
if (customCollections.size() > 0) {
for (auto it = customCollections.begin(); it != customCollections.end(); it++) {
FileFilterIndex* customIndex = (*it)->getSystem()->getIndex();
if (customIndex->isFiltered()) {
std::vector<FileData*> customChildren = (*it)->getChildrenListToDisplay();
if (customChildren.size() == 0)
customIndex->resetFilters();
}
}
}
}
mFilterIndex->resetFilters(); mFilterIndex->resetFilters();
for (std::map<FilterIndexType, std::shared_ptr< OptionListComponent<std::string>>>:: for (std::map<FilterIndexType, std::shared_ptr< OptionListComponent<std::string>>>::
const_iterator it = mFilterOptions.cbegin(); it != mFilterOptions.cend(); ++it ) { const_iterator it = mFilterOptions.cbegin(); it != mFilterOptions.cend(); ++it ) {

View file

@ -26,7 +26,7 @@ BasicGameListView::BasicGameListView(Window* window, FileData* root)
mList.setDefaultZIndex(20); mList.setDefaultZIndex(20);
addChild(&mList); addChild(&mList);
populateList(root->getChildrenListToDisplay()); populateList(root->getChildrenListToDisplay(), root);
} }
void BasicGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme) void BasicGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
@ -49,7 +49,7 @@ void BasicGameListView::onFileChanged(FileData* file, bool reloadGameList)
ISimpleGameListView::onFileChanged(file, reloadGameList); ISimpleGameListView::onFileChanged(file, reloadGameList);
} }
void BasicGameListView::populateList(const std::vector<FileData*>& files) void BasicGameListView::populateList(const std::vector<FileData*>& files, FileData* firstEntry)
{ {
mFirstGameEntry = nullptr; mFirstGameEntry = nullptr;
bool favoriteStar = true; bool favoriteStar = true;
@ -57,9 +57,6 @@ void BasicGameListView::populateList(const std::vector<FileData*>& files)
std::string editingCollection; std::string editingCollection;
std::string inCollectionPrefix; std::string inCollectionPrefix;
generateGamelistInfo(files);
generateFirstLetterIndex(files);
if (CollectionSystemManager::get()->isEditing()) { if (CollectionSystemManager::get()->isEditing()) {
editingCollection = CollectionSystemManager::get()->getEditingCollection(); editingCollection = CollectionSystemManager::get()->getEditingCollection();
isEditing = true; isEditing = true;
@ -103,8 +100,11 @@ void BasicGameListView::populateList(const std::vector<FileData*>& files)
} }
} }
else { else {
addPlaceholder(); addPlaceholder(firstEntry);
} }
generateGamelistInfo(getCursor(), firstEntry);
generateFirstLetterIndex(files);
} }
FileData* BasicGameListView::getCursor() FileData* BasicGameListView::getCursor()
@ -115,7 +115,7 @@ FileData* BasicGameListView::getCursor()
void BasicGameListView::setCursor(FileData* cursor) void BasicGameListView::setCursor(FileData* cursor)
{ {
if (!mList.setCursor(cursor) && (!cursor->isPlaceHolder())) { if (!mList.setCursor(cursor) && (!cursor->isPlaceHolder())) {
populateList(cursor->getParent()->getChildrenListToDisplay()); populateList(cursor->getParent()->getChildrenListToDisplay(), cursor->getParent());
mList.setCursor(cursor); mList.setCursor(cursor);
// Update our cursor stack in case our cursor just // Update our cursor stack in case our cursor just
@ -163,11 +163,17 @@ FileData* BasicGameListView::getFirstGameEntry()
return mFirstGameEntry; return mFirstGameEntry;
} }
void BasicGameListView::addPlaceholder() void BasicGameListView::addPlaceholder(FileData* firstEntry)
{ {
// Empty list - add a placeholder. // Empty list - add a placeholder.
SystemData* system;
if (firstEntry && firstEntry->getSystem()->isGroupedCustomCollection())
system = firstEntry->getSystem();
else
system = this->mRoot->getSystem();
FileData* placeholder = new FileData(PLACEHOLDER, "<No Entries Found>", FileData* placeholder = new FileData(PLACEHOLDER, "<No Entries Found>",
this->mRoot->getSystem()->getSystemEnvData(), this->mRoot->getSystem()); this->mRoot->getSystem()->getSystemEnvData(), system);
mList.add(placeholder->getName(), placeholder, (placeholder->getType() == PLACEHOLDER)); mList.add(placeholder->getName(), placeholder, (placeholder->getType() == PLACEHOLDER));
} }

View file

@ -44,10 +44,10 @@ public:
protected: protected:
virtual std::string getQuickSystemSelectRightButton() override; virtual std::string getQuickSystemSelectRightButton() override;
virtual std::string getQuickSystemSelectLeftButton() override; virtual std::string getQuickSystemSelectLeftButton() override;
virtual void populateList(const std::vector<FileData*>& files) override; virtual void populateList(const std::vector<FileData*>& files, FileData* firstEntry) override;
virtual void remove(FileData* game, bool deleteFile) override; virtual void remove(FileData* game, bool deleteFile) override;
virtual void removeMedia(FileData* game) override; virtual void removeMedia(FileData* game) override;
virtual void addPlaceholder(); virtual void addPlaceholder(FileData* firstEntry = nullptr);
TextListComponent<FileData*> mList; TextListComponent<FileData*> mList;
// Points to the first game in the list, i.e. the first entry which is of the type 'GAME'. // Points to the first game in the list, i.e. the first entry which is of the type 'GAME'.

View file

@ -71,7 +71,7 @@ GridGameListView::GridGameListView(
mGrid.setCursorChangedCallback([&](const CursorState& /*state*/) { updateInfoPanel(); }); mGrid.setCursorChangedCallback([&](const CursorState& /*state*/) { updateInfoPanel(); });
addChild(&mGrid); addChild(&mGrid);
populateList(root->getChildrenListToDisplay()); populateList(root->getChildrenListToDisplay(), root);
// Metadata labels + values. // Metadata labels + values.
mLblRating.setText("Rating: "); mLblRating.setText("Rating: ");
@ -162,8 +162,8 @@ FileData* GridGameListView::getCursor()
void GridGameListView::setCursor(FileData* file) void GridGameListView::setCursor(FileData* file)
{ {
if (!mGrid.setCursor(file)) { if (!mGrid.setCursor(file) && (!file->isPlaceHolder())) {
populateList(file->getParent()->getChildrenListToDisplay()); populateList(file->getParent()->getChildrenListToDisplay(), file->getParent());
mGrid.setCursor(file); mGrid.setCursor(file);
} }
} }
@ -244,13 +244,10 @@ const std::string GridGameListView::getImagePath(FileData* file)
return file->getThumbnailPath(); return file->getThumbnailPath();
} }
void GridGameListView::populateList(const std::vector<FileData*>& files) void GridGameListView::populateList(const std::vector<FileData*>& files, FileData* firstEntry)
{ {
firstGameEntry = nullptr; firstGameEntry = nullptr;
generateGamelistInfo(files);
generateFirstLetterIndex(files);
mGrid.clear(); mGrid.clear();
mHeaderText.setText(mRoot->getSystem()->getFullName()); mHeaderText.setText(mRoot->getSystem()->getFullName());
if (files.size() > 0) { if (files.size() > 0) {
@ -261,8 +258,11 @@ void GridGameListView::populateList(const std::vector<FileData*>& files)
} }
} }
else { else {
addPlaceholder(); addPlaceholder(firstEntry);
} }
generateGamelistInfo(getCursor(), firstEntry);
generateFirstLetterIndex(files);
} }
void GridGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme) void GridGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
@ -310,7 +310,7 @@ void GridGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
// Repopulate list in case a new theme is displaying a different image. // Repopulate list in case a new theme is displaying a different image.
// Preserve selection. // Preserve selection.
FileData* file = mGrid.getSelected(); FileData* file = mGrid.getSelected();
populateList(mRoot->getChildrenListToDisplay()); populateList(mRoot->getChildrenListToDisplay(), mRoot);
mGrid.setCursor(file); mGrid.setCursor(file);
mGamelistInfo.applyTheme(theme, getName(), "gamelistInfo", ALL ^ ThemeFlags::TEXT); mGamelistInfo.applyTheme(theme, getName(), "gamelistInfo", ALL ^ ThemeFlags::TEXT);
@ -517,11 +517,17 @@ void GridGameListView::updateInfoPanel()
} }
} }
void GridGameListView::addPlaceholder() void GridGameListView::addPlaceholder(FileData* firstEntry)
{ {
// Empty grid - add a placeholder. // Empty list - add a placeholder.
SystemData* system;
if (firstEntry && firstEntry->getSystem()->isGroupedCustomCollection())
system = firstEntry->getSystem();
else
system = this->mRoot->getSystem();
FileData* placeholder = new FileData(PLACEHOLDER, "<No Entries Found>", FileData* placeholder = new FileData(PLACEHOLDER, "<No Entries Found>",
this->mRoot->getSystem()->getSystemEnvData(), this->mRoot->getSystem()); this->mRoot->getSystem()->getSystemEnvData(), system);
mGrid.add(placeholder->getName(), "", placeholder); mGrid.add(placeholder->getName(), "", placeholder);
} }

View file

@ -48,10 +48,10 @@ protected:
virtual void update(int deltaTime) override; virtual void update(int deltaTime) override;
virtual std::string getQuickSystemSelectRightButton() override; virtual std::string getQuickSystemSelectRightButton() override;
virtual std::string getQuickSystemSelectLeftButton() override; virtual std::string getQuickSystemSelectLeftButton() override;
virtual void populateList(const std::vector<FileData*>& files) override; virtual void populateList(const std::vector<FileData*>& files, FileData* firstEntry) override;
virtual void remove(FileData* game, bool deleteFile) override; virtual void remove(FileData* game, bool deleteFile) override;
virtual void removeMedia(FileData* game) override; virtual void removeMedia(FileData* game) override;
virtual void addPlaceholder(); virtual void addPlaceholder(FileData* firstEntry = nullptr);
ImageGridComponent<FileData*> mGrid; ImageGridComponent<FileData*> mGrid;
// Points to the first game in the list, i.e. the first entry which is of the type 'GAME'. // Points to the first game in the list, i.e. the first entry which is of the type 'GAME'.

View file

@ -89,11 +89,11 @@ void ISimpleGameListView::onFileChanged(FileData* file, bool reloadGameList)
// but this shouldn't happen very often so we'll just always repopulate. // but this shouldn't happen very often so we'll just always repopulate.
FileData* cursor = getCursor(); FileData* cursor = getCursor();
if (!cursor->isPlaceHolder()) { if (!cursor->isPlaceHolder()) {
populateList(cursor->getParent()->getChildrenListToDisplay()); populateList(cursor->getParent()->getChildrenListToDisplay(), cursor->getParent());
setCursor(cursor); setCursor(cursor);
} }
else { else {
populateList(mRoot->getChildrenListToDisplay()); populateList(mRoot->getChildrenListToDisplay(), mRoot);
setCursor(cursor); setCursor(cursor);
} }
} }
@ -114,7 +114,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
ViewController::get()->resetMovingCamera(); ViewController::get()->resetMovingCamera();
NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND);
mCursorStack.push(cursor); mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay()); populateList(cursor->getChildrenListToDisplay(), cursor);
FileData* cursor = getCursor(); FileData* cursor = getCursor();
setCursor(cursor); setCursor(cursor);
} }
@ -126,7 +126,8 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
ViewController::get()->resetMovingCamera(); ViewController::get()->resetMovingCamera();
if (mCursorStack.size()) { if (mCursorStack.size()) {
NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND);
populateList(mCursorStack.top()->getParent()->getChildrenListToDisplay()); populateList(mCursorStack.top()->getParent()->getChildrenListToDisplay(),
mCursorStack.top()->getParent());
setCursor(mCursorStack.top()); setCursor(mCursorStack.top());
if (mCursorStack.size() > 0) if (mCursorStack.size() > 0)
mCursorStack.pop(); mCursorStack.pop();
@ -345,15 +346,16 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
return IGameListView::input(config, input); return IGameListView::input(config, input);
} }
void ISimpleGameListView::generateGamelistInfo(const std::vector<FileData*>& files) void ISimpleGameListView::generateGamelistInfo(FileData* cursor, FileData* firstEntry)
{ {
// Generate data needed for the gamelistInfo field, which is displayed from the // Generate data needed for the gamelistInfo field, which is displayed from the
// gamelist interfaces (Detailed/Video/Grid). // gamelist interfaces (Detailed/Video/Grid).
mIsFiltered = false; mIsFiltered = false;
mIsFolder = false; mIsFolder = false;
FileData* rootFolder = firstEntry->getSystem()->getRootFolder();
std::pair<unsigned int, unsigned int> gameCount; std::pair<unsigned int, unsigned int> gameCount;
FileFilterIndex* idx = mRoot->getSystem()->getIndex(); FileFilterIndex* idx = rootFolder->getSystem()->getIndex();
// For the 'recent' collection we need to recount the games as the collection was // For the 'recent' collection we need to recount the games as the collection was
// trimmed down to 50 items. If we don't do this, the game count will not be correct // trimmed down to 50 items. If we don't do this, the game count will not be correct
@ -361,11 +363,7 @@ void ISimpleGameListView::generateGamelistInfo(const std::vector<FileData*>& fil
if (mRoot->getPath() == "recent") if (mRoot->getPath() == "recent")
mRoot->countGames(gameCount); mRoot->countGames(gameCount);
if (files.size() > 0 && files.front()->getParent() != mRoot && gameCount = rootFolder->getGameCount();
files.front()->getSystem()->isGroupedCustomCollection())
gameCount = files.front()->getSystem()->getRootFolder()->getGameCount();
else
gameCount = mRoot->getGameCount();
mGameCount = gameCount.first + gameCount.second; mGameCount = gameCount.first + gameCount.second;
mFavoritesGameCount = gameCount.second; mFavoritesGameCount = gameCount.second;
@ -374,14 +372,14 @@ void ISimpleGameListView::generateGamelistInfo(const std::vector<FileData*>& fil
if (idx->isFiltered()) { if (idx->isFiltered()) {
mIsFiltered = true; mIsFiltered = true;
mFilteredGameCount = mRoot->getFilesRecursive(GAME, true, false).size(); mFilteredGameCount = rootFolder->getFilesRecursive(GAME, true, false).size();
// Also count the games that are set to not be counted as games, as the filter may // Also count the games that are set to not be counted as games, as the filter may
// apply to such entries as well and this will be indicated with a separate '+ XX' // apply to such entries as well and this will be indicated with a separate '+ XX'
// in the GamelistInfo field. // in the GamelistInfo field.
mFilteredGameCountAll = mRoot->getFilesRecursive(GAME, true, true).size(); mFilteredGameCountAll = rootFolder->getFilesRecursive(GAME, true, true).size();
} }
if (files.size() > 0 && files.front()->getParent() != mRoot) if (firstEntry->getParent() && firstEntry->getParent()->getType() == FOLDER)
mIsFolder = true; mIsFolder = true;
} }

View file

@ -38,9 +38,9 @@ public:
protected: protected:
virtual std::string getQuickSystemSelectRightButton() = 0; virtual std::string getQuickSystemSelectRightButton() = 0;
virtual std::string getQuickSystemSelectLeftButton() = 0; virtual std::string getQuickSystemSelectLeftButton() = 0;
virtual void populateList(const std::vector<FileData*>& files) = 0; virtual void populateList(const std::vector<FileData*>& files, FileData* firstEntry) = 0;
void generateGamelistInfo(const std::vector<FileData*>& files); void generateGamelistInfo(FileData* cursor, FileData* firstEntry);
void generateFirstLetterIndex(const std::vector<FileData*>& files); void generateFirstLetterIndex(const std::vector<FileData*>& files);
TextComponent mHeaderText; TextComponent mHeaderText;