mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Moved game counting to the sort function and improved the custom collection handling.
This commit is contained in:
parent
c5ecfb4e36
commit
1c831249da
4
NEWS.md
4
NEWS.md
|
@ -23,7 +23,9 @@ Many bugs have been fixed, and numerous features that were only partially implem
|
||||||
* Updated scraper to support additional media files, detailed configuration of what to scrape, semi-automatic mode etc.
|
* Updated scraper to support additional media files, detailed configuration of what to scrape, semi-automatic mode etc.
|
||||||
* In the metadata editor, any values updated by the single-game scraper or by the user are now highlighted using a different font color
|
* In the metadata editor, any values updated by the single-game scraper or by the user are now highlighted using a different font color
|
||||||
* Files or folders can now be flagged for exclusion when scraping with the multi-scraper, and for folders it can be set to apply recursively
|
* Files or folders can now be flagged for exclusion when scraping with the multi-scraper, and for folders it can be set to apply recursively
|
||||||
* Gamelist sorting now working as expected and is persistent throughout the application session
|
* Gamelist sorting is now working as expected and is persistent throughout the application session
|
||||||
|
* Game counting is now done during sorting instead of every time a system is selected. This should make the UI more responsive in case of large game libraries
|
||||||
|
* Added a system view counter for favorite games in addition to the total number of games
|
||||||
* Added support for jumping to the start and end of gamelists and menus using the controller trigger buttons (or equivalent keyboard mappings)
|
* Added support for jumping to the start and end of gamelists and menus using the controller trigger buttons (or equivalent keyboard mappings)
|
||||||
* Full navigation sound support, configurable per theme with a fallback to the built-in sounds if the theme does not support it
|
* Full navigation sound support, configurable per theme with a fallback to the built-in sounds if the theme does not support it
|
||||||
* New default theme rbsimple-DE bundled with the software, this theme is largely based on recalbox-multi by the Recalbox community
|
* New default theme rbsimple-DE bundled with the software, this theme is largely based on recalbox-multi by the Recalbox community
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
|
// EmulationStation Desktop Edition
|
||||||
// CollectionSystemManager.cpp
|
// CollectionSystemManager.cpp
|
||||||
//
|
//
|
||||||
// Manages collections of the following two types:
|
// Manages collections of the following two types:
|
||||||
|
@ -30,8 +32,9 @@
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
#include <pugixml.hpp>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
std::string myCollectionsName = "collections";
|
std::string myCollectionsName = "collections";
|
||||||
|
|
||||||
|
@ -237,8 +240,7 @@ void CollectionSystemManager::updateSystemsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we were editing a custom collection, and it's no longer enabled, exit edit mode.
|
// If we were editing a custom collection, and it's no longer enabled, exit edit mode.
|
||||||
if (mIsEditingCustom && !mEditingCollectionSystemData->isEnabled)
|
if (mIsEditingCustom && !mEditingCollectionSystemData->isEnabled) {
|
||||||
{
|
|
||||||
exitEditMode();
|
exitEditMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,14 +387,18 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS
|
||||||
if (sysData.decl.isCustom &&
|
if (sysData.decl.isCustom &&
|
||||||
Settings::getInstance()->getBool("UseCustomCollectionsSystem")) {
|
Settings::getInstance()->getBool("UseCustomCollectionsSystem")) {
|
||||||
// In case of a returned null pointer, we know there is no parent.
|
// In case of a returned null pointer, we know there is no parent.
|
||||||
if (rootFolder->getParent() == nullptr)
|
if (rootFolder->getParent() == nullptr) {
|
||||||
ViewController::get()->onFileChanged(rootFolder, FILE_METADATA_CHANGED);
|
ViewController::get()->onFileChanged(rootFolder, FILE_METADATA_CHANGED);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
rootFolder->getParent()->sort(rootFolder->getSortTypeFromString(
|
||||||
|
rootFolder->getSortTypeString()), mFavoritesSorting);
|
||||||
ViewController::get()->onFileChanged(
|
ViewController::get()->onFileChanged(
|
||||||
rootFolder->getParent(), FILE_METADATA_CHANGED);
|
rootFolder->getParent(), FILE_METADATA_CHANGED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionSystemManager::trimCollectionCount(FileData* rootFolder, int limit)
|
void CollectionSystemManager::trimCollectionCount(FileData* rootFolder, int limit)
|
||||||
|
@ -591,6 +597,9 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file)
|
||||||
|
|
||||||
ViewController::get()->getGameListView(systemViewToUpdate).get()->
|
ViewController::get()->getGameListView(systemViewToUpdate).get()->
|
||||||
remove(collectionEntry, false);
|
remove(collectionEntry, false);
|
||||||
|
systemViewToUpdate->getRootFolder()->sort(rootFolder->getSortTypeFromString(
|
||||||
|
rootFolder->getSortTypeString()),
|
||||||
|
Settings::getInstance()->getBool("FavFirstCustom"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We didn't find it here, so we should add it.
|
// We didn't find it here, so we should add it.
|
||||||
|
@ -601,10 +610,6 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file)
|
||||||
onFileChanged(newGame, FILE_METADATA_CHANGED);
|
onFileChanged(newGame, FILE_METADATA_CHANGED);
|
||||||
if (name == "recent")
|
if (name == "recent")
|
||||||
rootFolder->sort(rootFolder->getSortTypeFromString("last played, descending"));
|
rootFolder->sort(rootFolder->getSortTypeFromString("last played, descending"));
|
||||||
else
|
|
||||||
rootFolder->sort(rootFolder->getSortTypeFromString(
|
|
||||||
rootFolder->getSortTypeString()),
|
|
||||||
Settings::getInstance()->getBool("FavFirstCustom"));
|
|
||||||
|
|
||||||
ViewController::get()->onFileChanged(systemViewToUpdate->
|
ViewController::get()->onFileChanged(systemViewToUpdate->
|
||||||
getRootFolder(), FILE_SORTED);
|
getRootFolder(), FILE_SORTED);
|
||||||
|
@ -612,6 +617,7 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file)
|
||||||
// Add to bundle index as well, if needed.
|
// Add to bundle index as well, if needed.
|
||||||
if (systemViewToUpdate != sysData)
|
if (systemViewToUpdate != sysData)
|
||||||
systemViewToUpdate->getIndex()->addToIndex(newGame);
|
systemViewToUpdate->getIndex()->addToIndex(newGame);
|
||||||
|
refreshCollectionSystems(newGame);
|
||||||
}
|
}
|
||||||
updateCollectionFolderMetadata(sysData);
|
updateCollectionFolderMetadata(sysData);
|
||||||
}
|
}
|
||||||
|
@ -783,15 +789,15 @@ SystemData* CollectionSystemManager::addNewCustomCollection(std::string name)
|
||||||
decl.name = name;
|
decl.name = name;
|
||||||
decl.longName = name;
|
decl.longName = name;
|
||||||
|
|
||||||
return createNewCollectionEntry(name, decl);
|
return createNewCollectionEntry(name, decl, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new empty collection system based on the name and declaration.
|
// Create a new empty collection system based on the name and declaration.
|
||||||
SystemData* CollectionSystemManager::createNewCollectionEntry(
|
SystemData* CollectionSystemManager::createNewCollectionEntry(
|
||||||
std::string name, CollectionSystemDecl sysDecl, bool index)
|
std::string name, CollectionSystemDecl sysDecl, bool index, bool custom)
|
||||||
{
|
{
|
||||||
SystemData* newSys = new SystemData(
|
SystemData* newSys = new SystemData(
|
||||||
name, sysDecl.longName, mCollectionEnvData, sysDecl.themeFolder, true);
|
name, sysDecl.longName, mCollectionEnvData, sysDecl.themeFolder, true, custom);
|
||||||
|
|
||||||
CollectionSystemData newCollectionData;
|
CollectionSystemData newCollectionData;
|
||||||
newCollectionData.system = newSys;
|
newCollectionData.system = newSys;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
|
// EmulationStation Desktop Edition
|
||||||
// CollectionSystemManager.h
|
// CollectionSystemManager.h
|
||||||
//
|
//
|
||||||
// Manages collections of the following two types:
|
// Manages collections of the following two types:
|
||||||
|
@ -17,7 +19,6 @@
|
||||||
// the required re-sort and refresh of the gamelists.
|
// the required re-sort and refresh of the gamelists.
|
||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef ES_APP_COLLECTION_SYSTEM_MANAGER_H
|
#ifndef ES_APP_COLLECTION_SYSTEM_MANAGER_H
|
||||||
#define ES_APP_COLLECTION_SYSTEM_MANAGER_H
|
#define ES_APP_COLLECTION_SYSTEM_MANAGER_H
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ private:
|
||||||
void initCustomCollectionSystems();
|
void initCustomCollectionSystems();
|
||||||
SystemData* getAllGamesCollection();
|
SystemData* getAllGamesCollection();
|
||||||
SystemData* createNewCollectionEntry(std::string name,
|
SystemData* createNewCollectionEntry(std::string name,
|
||||||
CollectionSystemDecl sysDecl, bool index = true);
|
CollectionSystemDecl sysDecl, bool index = true, bool custom = false);
|
||||||
void populateAutoCollection(CollectionSystemData* sysData);
|
void populateAutoCollection(CollectionSystemData* sysData);
|
||||||
void populateCustomCollection(CollectionSystemData* sysData);
|
void populateCustomCollection(CollectionSystemData* sysData);
|
||||||
|
|
||||||
|
@ -126,9 +127,7 @@ private:
|
||||||
std::vector<std::string> getUserCollectionThemeFolders();
|
std::vector<std::string> getUserCollectionThemeFolders();
|
||||||
|
|
||||||
void trimCollectionCount(FileData* rootFolder, int limit);
|
void trimCollectionCount(FileData* rootFolder, int limit);
|
||||||
|
|
||||||
bool themeFolderExists(std::string folder);
|
bool themeFolderExists(std::string folder);
|
||||||
|
|
||||||
bool includeFileInAutoCollections(FileData* file);
|
bool includeFileInAutoCollections(FileData* file);
|
||||||
|
|
||||||
SystemData* mCustomCollectionsBundle;
|
SystemData* mCustomCollectionsBundle;
|
||||||
|
|
|
@ -436,7 +436,8 @@ void FileData::removeChild(FileData* file)
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
void FileData::sort(ComparisonFunction& comparator, bool ascending,
|
||||||
|
std::pair<unsigned int, unsigned int>& gameCount)
|
||||||
{
|
{
|
||||||
mFirstLetterIndex.clear();
|
mFirstLetterIndex.clear();
|
||||||
mOnlyFolders = true;
|
mOnlyFolders = true;
|
||||||
|
@ -507,6 +508,14 @@ void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = mChildren.cbegin(); it != mChildren.cend(); it++) {
|
for (auto it = mChildren.cbegin(); it != mChildren.cend(); it++) {
|
||||||
|
// Game count, which will be displayed in the system view.
|
||||||
|
if ((*it)->getType() == GAME && (*it)->getCountAsGame()) {
|
||||||
|
if (!(*it)->getFavorite())
|
||||||
|
gameCount.first++;
|
||||||
|
else
|
||||||
|
gameCount.second++;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*it)->getType() != FOLDER)
|
if ((*it)->getType() != FOLDER)
|
||||||
mOnlyFolders = false;
|
mOnlyFolders = false;
|
||||||
|
|
||||||
|
@ -517,7 +526,7 @@ void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
||||||
}
|
}
|
||||||
// Iterate through any child folders.
|
// Iterate through any child folders.
|
||||||
if ((*it)->getChildren().size() > 0)
|
if ((*it)->getChildren().size() > 0)
|
||||||
(*it)->sort(comparator, ascending);
|
(*it)->sort(comparator, ascending, gameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are only folders in the gamelist, then it makes sense to still
|
// If there are only folders in the gamelist, then it makes sense to still
|
||||||
|
@ -540,7 +549,8 @@ void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
||||||
mFirstLetterIndex.insert(mFirstLetterIndex.begin(), FOLDER_CHAR);
|
mFirstLetterIndex.insert(mFirstLetterIndex.begin(), FOLDER_CHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending)
|
void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending,
|
||||||
|
std::pair<unsigned int, unsigned int>& gameCount)
|
||||||
{
|
{
|
||||||
mFirstLetterIndex.clear();
|
mFirstLetterIndex.clear();
|
||||||
mOnlyFolders = true;
|
mOnlyFolders = true;
|
||||||
|
@ -560,6 +570,14 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Game count, which will be displayed in the system view.
|
||||||
|
if (mChildren[i]->getType() == GAME && mChildren[i]->getCountAsGame()) {
|
||||||
|
if (!mChildren[i]->getFavorite())
|
||||||
|
gameCount.first++;
|
||||||
|
else
|
||||||
|
gameCount.second++;
|
||||||
|
}
|
||||||
|
|
||||||
if (foldersOnTop && mChildren[i]->getType() == FOLDER) {
|
if (foldersOnTop && mChildren[i]->getType() == FOLDER) {
|
||||||
if (!mChildren[i]->getFavorite())
|
if (!mChildren[i]->getFavorite())
|
||||||
mChildrenFolders.push_back(mChildren[i]);
|
mChildrenFolders.push_back(mChildren[i]);
|
||||||
|
@ -664,13 +682,13 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
||||||
for (auto it = mChildrenFavoritesFolders.cbegin(); it !=
|
for (auto it = mChildrenFavoritesFolders.cbegin(); it !=
|
||||||
mChildrenFavoritesFolders.cend(); it++) {
|
mChildrenFavoritesFolders.cend(); it++) {
|
||||||
if ((*it)->getChildren().size() > 0)
|
if ((*it)->getChildren().size() > 0)
|
||||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
(*it)->sortFavoritesOnTop(comparator, ascending, gameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through any child folders.
|
// Iterate through any child folders.
|
||||||
for (auto it = mChildrenFolders.cbegin(); it != mChildrenFolders.cend(); it++) {
|
for (auto it = mChildrenFolders.cbegin(); it != mChildrenFolders.cend(); it++) {
|
||||||
if ((*it)->getChildren().size() > 0)
|
if ((*it)->getChildren().size() > 0)
|
||||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
(*it)->sortFavoritesOnTop(comparator, ascending, gameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ascending) {
|
if (!ascending) {
|
||||||
|
@ -695,10 +713,12 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
||||||
|
|
||||||
void FileData::sort(const SortType& type, bool mFavoritesOnTop)
|
void FileData::sort(const SortType& type, bool mFavoritesOnTop)
|
||||||
{
|
{
|
||||||
|
mGameCount = std::make_pair(0, 0);
|
||||||
|
|
||||||
if (mFavoritesOnTop)
|
if (mFavoritesOnTop)
|
||||||
sortFavoritesOnTop(*type.comparisonFunction, type.ascending);
|
sortFavoritesOnTop(*type.comparisonFunction, type.ascending, mGameCount);
|
||||||
else
|
else
|
||||||
sort(*type.comparisonFunction, type.ascending);
|
sort(*type.comparisonFunction, type.ascending, mGameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileData::SortType FileData::getSortTypeFromString(std::string desc) {
|
FileData::SortType FileData::getSortTypeFromString(std::string desc) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
const bool getFavorite();
|
const bool getFavorite();
|
||||||
const bool getHidden();
|
const bool getHidden();
|
||||||
const bool getCountAsGame();
|
const bool getCountAsGame();
|
||||||
|
const std::pair<unsigned int, unsigned int> getGameCount() { return mGameCount; };
|
||||||
const bool getExcludeFromScraper();
|
const bool getExcludeFromScraper();
|
||||||
const std::vector<FileData*> getChildrenRecursive() const;
|
const std::vector<FileData*> getChildrenRecursive() const;
|
||||||
inline FileType getType() const { return mType; }
|
inline FileType getType() const { return mType; }
|
||||||
|
@ -123,8 +124,10 @@ public:
|
||||||
description(sortDescription) {}
|
description(sortDescription) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void sort(ComparisonFunction& comparator, bool ascending = true);
|
void sort(ComparisonFunction& comparator, bool ascending,
|
||||||
void sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending = true);
|
std::pair<unsigned int, unsigned int>& gameCount);
|
||||||
|
void sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending,
|
||||||
|
std::pair<unsigned int, unsigned int>& gameCount);
|
||||||
void sort(const SortType& type, bool mFavoritesOnTop = false);
|
void sort(const SortType& type, bool mFavoritesOnTop = false);
|
||||||
MetaDataList metadata;
|
MetaDataList metadata;
|
||||||
|
|
||||||
|
@ -151,6 +154,8 @@ private:
|
||||||
std::vector<FileData*> mChildren;
|
std::vector<FileData*> mChildren;
|
||||||
std::vector<FileData*> mFilteredChildren;
|
std::vector<FileData*> mFilteredChildren;
|
||||||
std::vector<std::string> mFirstLetterIndex;
|
std::vector<std::string> mFirstLetterIndex;
|
||||||
|
// The pair includes non-favorite games, and favorite games.
|
||||||
|
std::pair<unsigned int, unsigned int> mGameCount;
|
||||||
bool mOnlyFolders;
|
bool mOnlyFolders;
|
||||||
// Used for flagging a game for deletion from its gamelist.xml file.
|
// Used for flagging a game for deletion from its gamelist.xml file.
|
||||||
bool mDeletionFlag;
|
bool mDeletionFlag;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
|
// EmulationStation Desktop Edition
|
||||||
// SystemData.cpp
|
// SystemData.cpp
|
||||||
//
|
//
|
||||||
// Provides data structures for the game systems and populates and indexes them based
|
// Provides data structures for the game systems and populates and indexes them based
|
||||||
|
@ -12,6 +14,7 @@
|
||||||
#include "resources/ResourceManager.h"
|
#include "resources/ResourceManager.h"
|
||||||
#include "utils/FileSystemUtil.h"
|
#include "utils/FileSystemUtil.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
#include "views/UIModeController.h"
|
||||||
#include "CollectionSystemManager.h"
|
#include "CollectionSystemManager.h"
|
||||||
#include "FileFilterIndex.h"
|
#include "FileFilterIndex.h"
|
||||||
#include "FileSorts.h"
|
#include "FileSorts.h"
|
||||||
|
@ -20,10 +23,9 @@
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
#include "views/UIModeController.h"
|
|
||||||
|
|
||||||
#include <pugixml.hpp>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
std::vector<SystemData*> SystemData::sSystemVector;
|
std::vector<SystemData*> SystemData::sSystemVector;
|
||||||
|
|
||||||
|
@ -32,12 +34,14 @@ SystemData::SystemData(
|
||||||
const std::string& fullName,
|
const std::string& fullName,
|
||||||
SystemEnvironmentData* envData,
|
SystemEnvironmentData* envData,
|
||||||
const std::string& themeFolder,
|
const std::string& themeFolder,
|
||||||
bool CollectionSystem)
|
bool CollectionSystem,
|
||||||
|
bool CustomCollectionSystem)
|
||||||
: mName(name),
|
: mName(name),
|
||||||
mFullName(fullName),
|
mFullName(fullName),
|
||||||
mEnvData(envData),
|
mEnvData(envData),
|
||||||
mThemeFolder(themeFolder),
|
mThemeFolder(themeFolder),
|
||||||
mIsCollectionSystem(CollectionSystem),
|
mIsCollectionSystem(CollectionSystem),
|
||||||
|
mIsCustomCollectionSystem(CustomCollectionSystem),
|
||||||
mIsGameSystem(true),
|
mIsGameSystem(true),
|
||||||
mScrapeFlag(false)
|
mScrapeFlag(false)
|
||||||
{
|
{
|
||||||
|
@ -402,9 +406,11 @@ std::string SystemData::getConfigPath(bool forWrite)
|
||||||
|
|
||||||
bool SystemData::isVisible()
|
bool SystemData::isVisible()
|
||||||
{
|
{
|
||||||
return (getDisplayedGameCount() > 0 ||
|
// This function doesn't make much sense at the moment; if a game system does not have any
|
||||||
(UIModeController::getInstance()->isUIModeFull() && mIsCollectionSystem) ||
|
// games available, it will not be processed during startup and will as such not exist.
|
||||||
(mIsCollectionSystem && mName == "favorites"));
|
// In the future this function may be used for an option to hide specific systems, but
|
||||||
|
// for the time being all systems will always be visible.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemData* SystemData::getNext() const
|
SystemData* SystemData::getNext() const
|
||||||
|
@ -488,11 +494,6 @@ bool SystemData::hasGamelist() const
|
||||||
return (Utils::FileSystem::exists(getGamelistPath(false)));
|
return (Utils::FileSystem::exists(getGamelistPath(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SystemData::getGameCount() const
|
|
||||||
{
|
|
||||||
return (unsigned int)mRootFolder->getFilesRecursive(GAME).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemData* SystemData::getRandomSystem(const SystemData* currentSystem)
|
SystemData* SystemData::getRandomSystem(const SystemData* currentSystem)
|
||||||
{
|
{
|
||||||
unsigned int total = 0;
|
unsigned int total = 0;
|
||||||
|
@ -612,10 +613,12 @@ FileData* SystemData::getRandomGame(const FileData* currentGame)
|
||||||
return gameList.at(target);
|
return gameList.at(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SystemData::getDisplayedGameCount() const
|
std::pair<unsigned int, unsigned int> SystemData::getDisplayedGameCount() const
|
||||||
{
|
{
|
||||||
// Pass the flag to only count games that are marked with the flag 'countasgame'.
|
// Return all games for the system which are marked as 'countasgame'. As this flag is set
|
||||||
return (unsigned int)mRootFolder->getFilesRecursive(GAME, true, false).size();
|
// by default, normally most games will be included in the number returned from here.
|
||||||
|
// The actual game counting takes place in FileData during sorting.
|
||||||
|
return mRootFolder->getGameCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemData::loadTheme()
|
void SystemData::loadTheme()
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
|
// EmulationStation Desktop Edition
|
||||||
// SystemData.h
|
// SystemData.h
|
||||||
//
|
//
|
||||||
// Provides data structures for the game systems and populates and indexes them based
|
// Provides data structures for the game systems and populates and indexes them based
|
||||||
|
@ -7,7 +9,6 @@
|
||||||
// loading.
|
// loading.
|
||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef ES_APP_SYSTEM_DATA_H
|
#ifndef ES_APP_SYSTEM_DATA_H
|
||||||
#define ES_APP_SYSTEM_DATA_H
|
#define ES_APP_SYSTEM_DATA_H
|
||||||
|
|
||||||
|
@ -36,7 +37,8 @@ public:
|
||||||
const std::string& fullName,
|
const std::string& fullName,
|
||||||
SystemEnvironmentData* envData,
|
SystemEnvironmentData* envData,
|
||||||
const std::string& themeFolder,
|
const std::string& themeFolder,
|
||||||
bool CollectionSystem = false);
|
bool CollectionSystem = false,
|
||||||
|
bool CustomCollectionSystem = false);
|
||||||
|
|
||||||
~SystemData();
|
~SystemData();
|
||||||
|
|
||||||
|
@ -60,8 +62,7 @@ public:
|
||||||
bool hasGamelist() const;
|
bool hasGamelist() const;
|
||||||
std::string getThemePath() const;
|
std::string getThemePath() const;
|
||||||
|
|
||||||
unsigned int getGameCount() const;
|
std::pair<unsigned int, unsigned int> getDisplayedGameCount() const;
|
||||||
unsigned int getDisplayedGameCount() const;
|
|
||||||
bool getScrapeFlag() { return mScrapeFlag; };
|
bool getScrapeFlag() { return mScrapeFlag; };
|
||||||
void setScrapeFlag(bool scrapeflag) { mScrapeFlag = scrapeflag; }
|
void setScrapeFlag(bool scrapeflag) { mScrapeFlag = scrapeflag; }
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ public:
|
||||||
inline std::vector<SystemData*>::const_reverse_iterator getRevIterator() const
|
inline std::vector<SystemData*>::const_reverse_iterator getRevIterator() const
|
||||||
{ return std::find(sSystemVector.crbegin(), sSystemVector.crend(), this); };
|
{ return std::find(sSystemVector.crbegin(), sSystemVector.crend(), this); };
|
||||||
inline bool isCollection() { return mIsCollectionSystem; };
|
inline bool isCollection() { return mIsCollectionSystem; };
|
||||||
|
inline bool isCustomCollection() { return mIsCustomCollectionSystem; };
|
||||||
inline bool isGameSystem() { return mIsGameSystem; };
|
inline bool isGameSystem() { return mIsGameSystem; };
|
||||||
|
|
||||||
bool isVisible();
|
bool isVisible();
|
||||||
|
@ -101,6 +103,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mIsCollectionSystem;
|
bool mIsCollectionSystem;
|
||||||
|
bool mIsCustomCollectionSystem;
|
||||||
bool mIsGameSystem;
|
bool mIsGameSystem;
|
||||||
bool mScrapeFlag; // Only used by scraper GUI to remember which systems to scrape.
|
bool mScrapeFlag; // Only used by scraper GUI to remember which systems to scrape.
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
|
@ -283,16 +283,25 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
||||||
Math::lerp(infoStartOpacity, 0.f, t) * 255));
|
Math::lerp(infoStartOpacity, 0.f, t) * 255));
|
||||||
}, static_cast<int>(infoStartOpacity * (goFast ? 10 : 150)));
|
}, static_cast<int>(infoStartOpacity * (goFast ? 10 : 150)));
|
||||||
|
|
||||||
unsigned int gameCount = getSelected()->getDisplayedGameCount();
|
std::pair<unsigned int, unsigned int> gameCount = getSelected()->getDisplayedGameCount();
|
||||||
|
|
||||||
// Also change the text after we've fully faded out.
|
// Also change the text after we've fully faded out.
|
||||||
setAnimation(infoFadeOut, 0, [this, gameCount] {
|
setAnimation(infoFadeOut, 0, [this, gameCount] {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
unsigned int totalGameCount = gameCount.first + gameCount.second;
|
||||||
|
|
||||||
if (!getSelected()->isGameSystem())
|
if (!getSelected()->isGameSystem())
|
||||||
ss << "CONFIGURATION";
|
ss << "CONFIGURATION";
|
||||||
|
else if (getSelected()->isCollection() && (getSelected()->getName() == "favorites"))
|
||||||
|
ss << totalGameCount << " GAME" << (totalGameCount == 1 ? " " : "S");
|
||||||
|
// The 'recent' gamelist has probably been trimmed after sorting, so we'll cap it at
|
||||||
|
// its maximum limit of 50 games.
|
||||||
|
else if (getSelected()->isCollection() && (getSelected()->getName() == "recent"))
|
||||||
|
ss << (totalGameCount > 50 ? 50 : totalGameCount) << " GAME" <<
|
||||||
|
(totalGameCount == 1 ? " " : "S");
|
||||||
else
|
else
|
||||||
ss << gameCount << " GAMES AVAILABLE";
|
ss << totalGameCount << " GAME" << (totalGameCount == 1 ? " " : "S ") << "(" <<
|
||||||
|
gameCount.second << " FAVORITE" << (gameCount.second == 1 ? ")" : "S)");
|
||||||
|
|
||||||
mSystemInfo.setText(ss.str());
|
mSystemInfo.setText(ss.str());
|
||||||
}, false, 1);
|
}, false, 1);
|
||||||
|
|
|
@ -200,7 +200,8 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
||||||
else
|
else
|
||||||
favoritesSorting = Settings::getInstance()->getBool("FavoritesFirst");
|
favoritesSorting = Settings::getInstance()->getBool("FavoritesFirst");
|
||||||
|
|
||||||
if (favoritesSorting && static_cast<std::string>(getName()) != "recent") {
|
if (favoritesSorting && static_cast<std::string>(
|
||||||
|
mRoot->getSystem()->getName()) != "recent") {
|
||||||
FileData* entryToSelect;
|
FileData* entryToSelect;
|
||||||
// Add favorite flag.
|
// Add favorite flag.
|
||||||
if (!getCursor()->getFavorite()) {
|
if (!getCursor()->getFavorite()) {
|
||||||
|
@ -300,9 +301,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
||||||
}
|
}
|
||||||
else if (CollectionSystemManager::get()->toggleGameInCollection(entryToUpdate)) {
|
else if (CollectionSystemManager::get()->toggleGameInCollection(entryToUpdate)) {
|
||||||
// Jump to the first entry in the gamelist if the last favorite was unmarked.
|
// Jump to the first entry in the gamelist if the last favorite was unmarked.
|
||||||
if (foldersOnTop && removedLastFavorite)
|
if (foldersOnTop && removedLastFavorite &&
|
||||||
|
!entryToUpdate->getSystem()->isCustomCollection())
|
||||||
setCursor(getFirstGameEntry());
|
setCursor(getFirstGameEntry());
|
||||||
else if (removedLastFavorite)
|
else if (removedLastFavorite &&
|
||||||
|
!entryToUpdate->getSystem()->isCustomCollection())
|
||||||
setCursor(getFirstEntry());
|
setCursor(getFirstEntry());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
#ifndef ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
|
#ifndef ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
|
||||||
#define ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
|
#define ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
|
||||||
|
|
||||||
|
#include "views/gamelist/IGameListView.h"
|
||||||
#include "components/ImageComponent.h"
|
#include "components/ImageComponent.h"
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
#include "views/gamelist/IGameListView.h"
|
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ protected:
|
||||||
ImageComponent mBackground;
|
ImageComponent mBackground;
|
||||||
|
|
||||||
std::vector<GuiComponent*> mThemeExtras;
|
std::vector<GuiComponent*> mThemeExtras;
|
||||||
|
|
||||||
std::stack<FileData*> mCursorStack;
|
std::stack<FileData*> mCursorStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue