mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 07:05:39 +00:00
Improved handling and sorting of folders.
This commit is contained in:
parent
2b82770e43
commit
e56fdf3df6
|
@ -151,6 +151,17 @@ const std::vector<FileData*> FileData::getChildrenRecursive() const
|
|||
return childrenRecursive;
|
||||
}
|
||||
|
||||
bool FileData::viewHasOnlyFolders()
|
||||
{
|
||||
bool onlyFolders = true;
|
||||
std::vector<FileData*> entrySiblings = this->getParent()->getChildren();
|
||||
for (auto it = entrySiblings.cbegin(); it != entrySiblings.cend(); it++) {
|
||||
if ((*it)->getType() != FOLDER)
|
||||
onlyFolders = false;
|
||||
}
|
||||
return onlyFolders;
|
||||
}
|
||||
|
||||
const std::string FileData::getROMDirectory()
|
||||
{
|
||||
std::string romDirSetting = Settings::getInstance()->getString("ROMDirectory");
|
||||
|
@ -463,6 +474,13 @@ void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
|||
}
|
||||
}
|
||||
|
||||
// If descending sorting is requested, always perform a ascending sort by filename first.
|
||||
// This adds a slight (probably negligible) overhead but it will avoid strange sorting
|
||||
// issues where the secondary sorting is reversed for some sort types.
|
||||
if (!ascending)
|
||||
std::stable_sort(mChildrenOthers.begin(), mChildrenOthers.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
|
||||
if (foldersOnTop && mOnlyFolders)
|
||||
std::stable_sort(mChildrenFolders.begin(), mChildrenFolders.end(), comparator);
|
||||
std::stable_sort(mChildrenOthers.begin(), mChildrenOthers.end(), comparator);
|
||||
|
@ -479,6 +497,10 @@ void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
|||
mChildren.insert(mChildren.end(), mChildrenOthers.begin(), mChildrenOthers.end());
|
||||
}
|
||||
else {
|
||||
if (!ascending)
|
||||
std::stable_sort(mChildren.begin(), mChildren.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
|
||||
std::stable_sort(mChildren.begin(), mChildren.end(), comparator);
|
||||
if (!ascending)
|
||||
std::reverse(mChildren.begin(), mChildren.end());
|
||||
|
@ -523,6 +545,7 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
|||
mFirstLetterIndex.clear();
|
||||
mOnlyFolders = true;
|
||||
std::vector<FileData*> mChildrenFolders;
|
||||
std::vector<FileData*> mChildrenFavoritesFolders;
|
||||
std::vector<FileData*> mChildrenFavorites;
|
||||
std::vector<FileData*> mChildrenOthers;
|
||||
bool showHiddenGames = Settings::getInstance()->getBool("ShowHiddenGames");
|
||||
|
@ -538,7 +561,11 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
|||
}
|
||||
|
||||
if (foldersOnTop && mChildren[i]->getType() == FOLDER) {
|
||||
if (!mChildren[i]->getFavorite())
|
||||
mChildrenFolders.push_back(mChildren[i]);
|
||||
else
|
||||
mChildrenFavoritesFolders.push_back(mChildren[i]);
|
||||
|
||||
hasFolders = true;
|
||||
}
|
||||
else if (mChildren[i]->getFavorite()) {
|
||||
|
@ -555,6 +582,19 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
|||
mOnlyFolders = false;
|
||||
}
|
||||
|
||||
// If there are favorite folders and this is a mixed list, then don't handle these
|
||||
// separately but instead merge them into the same vector. This is a quite wasteful
|
||||
// approach but the scenario where a user has a mixed folder and files list and marks
|
||||
// some folders as favorites is probably a rare situation.
|
||||
if (!mOnlyFolders && mChildrenFavoritesFolders.size() > 0) {
|
||||
mChildrenFolders.insert(mChildrenFolders.end(), mChildrenFavoritesFolders.begin(),
|
||||
mChildrenFavoritesFolders.end());
|
||||
mChildrenFavoritesFolders.erase(mChildrenFavoritesFolders.begin(),
|
||||
mChildrenFavoritesFolders.end());
|
||||
std::stable_sort(mChildrenFolders.begin(), mChildrenFolders.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
}
|
||||
|
||||
// If there are only favorites in the gamelist, it makes sense to still generate
|
||||
// a letter index. For instance to be able to quick jump in the 'favorites'
|
||||
// collection. Doing this additional work here only for the applicable gamelists is
|
||||
|
@ -584,49 +624,70 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending
|
|||
auto last = std::unique(mFirstLetterIndex.begin(), mFirstLetterIndex.end());
|
||||
mFirstLetterIndex.erase(last, mFirstLetterIndex.end());
|
||||
|
||||
// If there were at least one favorite folder in the gamelist, insert the favorite
|
||||
// unicode character in the first position.
|
||||
if (foldersOnTop && mOnlyFolders && mChildrenFavoritesFolders.size() > 0)
|
||||
mFirstLetterIndex.insert(mFirstLetterIndex.begin(), FAVORITE_CHAR);
|
||||
// If there were at least one favorite in the gamelist, insert the favorite
|
||||
// unicode character in the first position.
|
||||
if (mChildrenOthers.size() > 0 && mChildrenFavorites.size() > 0)
|
||||
else if (mChildrenOthers.size() > 0 && mChildrenFavorites.size() > 0)
|
||||
mFirstLetterIndex.insert(mFirstLetterIndex.begin(), FAVORITE_CHAR);
|
||||
|
||||
// If it's a mixed list and folders are sorted on top, add a folder icon to the index.
|
||||
if (foldersOnTop && hasFolders && !mOnlyFolders)
|
||||
mFirstLetterIndex.insert(mFirstLetterIndex.begin(), FOLDER_CHAR);
|
||||
|
||||
// If descending sorting is requested, always perform a ascending sort by filename first.
|
||||
// This adds a slight (probably negligible) overhead but it will avoid strange sorting
|
||||
// issues where the secondary sorting is reversed for some sort types.
|
||||
if (!ascending) {
|
||||
std::stable_sort(mChildrenFolders.begin(), mChildrenFolders.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
std::stable_sort(mChildrenFavoritesFolders.begin(), mChildrenFavoritesFolders.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
std::stable_sort(mChildrenFavorites.begin(), mChildrenFavorites.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
std::stable_sort(mChildrenOthers.begin(), mChildrenOthers.end(),
|
||||
getSortTypeFromString("filename, ascending").comparisonFunction);
|
||||
}
|
||||
|
||||
// Sort favorite games and the other games separately.
|
||||
if (foldersOnTop && mOnlyFolders)
|
||||
if (foldersOnTop && mOnlyFolders) {
|
||||
std::stable_sort(mChildrenFavoritesFolders.begin(),
|
||||
mChildrenFavoritesFolders.end(), comparator);
|
||||
std::stable_sort(mChildrenFolders.begin(), mChildrenFolders.end(), comparator);
|
||||
}
|
||||
std::stable_sort(mChildrenFavorites.begin(), mChildrenFavorites.end(), comparator);
|
||||
std::stable_sort(mChildrenOthers.begin(), mChildrenOthers.end(), comparator);
|
||||
|
||||
// Iterate through any child favorite folders.
|
||||
for (auto it = mChildrenFavoritesFolders.cbegin(); it !=
|
||||
mChildrenFavoritesFolders.cend(); it++) {
|
||||
if ((*it)->getChildren().size() > 0)
|
||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
||||
}
|
||||
|
||||
// Iterate through any child folders.
|
||||
for (auto it = mChildrenFolders.cbegin(); it != mChildrenFolders.cend(); it++) {
|
||||
if ((*it)->getChildren().size() > 0)
|
||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
||||
}
|
||||
|
||||
// Iterate through any child folders.
|
||||
for (auto it = mChildrenFavorites.cbegin(); it != mChildrenFavorites.cend(); it++) {
|
||||
if ((*it)->getChildren().size() > 0)
|
||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
||||
}
|
||||
|
||||
// Iterate through any child folders.
|
||||
for (auto it = mChildrenOthers.cbegin(); it != mChildrenOthers.cend(); it++) {
|
||||
if ((*it)->getChildren().size() > 0)
|
||||
(*it)->sortFavoritesOnTop(comparator, ascending);
|
||||
}
|
||||
|
||||
if (!ascending) {
|
||||
if (foldersOnTop && mOnlyFolders)
|
||||
if (foldersOnTop && mOnlyFolders) {
|
||||
std::reverse(mChildrenFavoritesFolders.begin(), mChildrenFavoritesFolders.end());
|
||||
std::reverse(mChildrenFolders.begin(), mChildrenFolders.end());
|
||||
}
|
||||
std::reverse(mChildrenFavorites.begin(), mChildrenFavorites.end());
|
||||
std::reverse(mChildrenOthers.begin(), mChildrenOthers.end());
|
||||
}
|
||||
|
||||
// Combine the individually sorted favorite games and other games vectors.
|
||||
mChildren.erase(mChildren.begin(), mChildren.end());
|
||||
mChildren.reserve(mChildrenFolders.size() + mChildrenFavorites.size() + mChildrenOthers.size());
|
||||
mChildren.reserve(mChildrenFavoritesFolders.size() + mChildrenFolders.size() +
|
||||
mChildrenFavorites.size() + mChildrenOthers.size());
|
||||
mChildren.insert(mChildren.end(), mChildrenFavoritesFolders.begin(),
|
||||
mChildrenFavoritesFolders.end());
|
||||
mChildren.insert(mChildren.end(), mChildrenFolders.begin(), mChildrenFolders.end());
|
||||
mChildren.insert(mChildren.end(), mChildrenFavorites.begin(), mChildrenFavorites.end());
|
||||
mChildren.insert(mChildren.end(), mChildrenOthers.begin(), mChildrenOthers.end());
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
const std::vector<std::string>& getFirstLetterIndex() const
|
||||
{ return mFirstLetterIndex; };
|
||||
const bool getOnlyFoldersFlag() { return mOnlyFolders; }
|
||||
bool viewHasOnlyFolders();
|
||||
static const std::string getROMDirectory();
|
||||
static const std::string getMediaDirectory();
|
||||
const std::string getMediafilePath(std::string subdirectory, std::string mediatype) const;
|
||||
|
|
|
@ -339,7 +339,7 @@ void GuiGamelistOptions::jumpToLetter()
|
|||
if (mFavoritesSorting && mFirstLetterIndex.front() == FAVORITE_CHAR) {
|
||||
if ((char)toupper(files.at(i)->getSortName().front()) ==
|
||||
letter && !files.at(i)->getFavorite()) {
|
||||
if (mFoldersOnTop && files.at(i)->getType() == FOLDER) {
|
||||
if (!mOnlyHasFolders && mFoldersOnTop && files.at(i)->getType() == FOLDER) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
@ -368,9 +368,13 @@ void GuiGamelistOptions::jumpToFirstRow()
|
|||
// Get the gamelist.
|
||||
const std::vector<FileData*>& files = getGamelist()->getCursor()->
|
||||
getParent()->getChildrenListToDisplay();
|
||||
// Select the first game that is not a folder.
|
||||
// Select the first game that is not a folder, unless it's a folder-only list in
|
||||
// which case the first line overall is selected.
|
||||
for (auto it = files.cbegin(); it != files.cend(); it++) {
|
||||
if ((*it)->getType() == GAME) {
|
||||
if (!mOnlyHasFolders && mFoldersOnTop && (*it)->getType() == FOLDER) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
getGamelist()->setCursor(*it);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -189,6 +189,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
|||
bool favoritesSorting;
|
||||
bool removedLastFavorite = false;
|
||||
bool foldersOnTop = Settings::getInstance()->getBool("FoldersOnTop");
|
||||
// If the current list only contains folders, then treat it as if the folders
|
||||
// are not sorted on top, this way the logic should work exactly as for mixed
|
||||
// lists or files-only lists.
|
||||
if (getCursor()->getType() == FOLDER && foldersOnTop == true)
|
||||
foldersOnTop = !getCursor()->viewHasOnlyFolders();
|
||||
|
||||
if (CollectionSystemManager::get()->getIsCustomCollection(mRoot->getSystem()))
|
||||
favoritesSorting = Settings::getInstance()->getBool("FavFirstCustom");
|
||||
|
@ -208,6 +213,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
|||
// If we are on the favorite marking boundary, select the next entry.
|
||||
else if (getCursor()->getFavorite() != getPreviousEntry()->getFavorite())
|
||||
entryToSelect = getNextEntry();
|
||||
// If we mark the second entry as favorite and the first entry is not a
|
||||
// favorite, then select this entry if they are of the same type.
|
||||
else if (getPreviousEntry() == getFirstEntry() &&
|
||||
getCursor()->getType() == getPreviousEntry()->getType())
|
||||
entryToSelect = getPreviousEntry();
|
||||
// For all other scenarios try to select the next entry, and if it doesn't
|
||||
// exist, select the previous entry.
|
||||
else
|
||||
|
@ -271,8 +281,8 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
|||
mWindow->setInfoPopup(s);
|
||||
entryToUpdate->getSourceFileData()->getSystem()->onMetaDataSavePoint();
|
||||
|
||||
if (!Settings::getInstance()->getBool("FoldersOnTop"))
|
||||
mRoot->sort(mRoot->getSortTypeFromString(mRoot->getSortTypeString()),
|
||||
getCursor()->getParent()->sort(
|
||||
mRoot->getSortTypeFromString(mRoot->getSortTypeString()),
|
||||
Settings::getInstance()->getBool("FavoritesFirst"));
|
||||
|
||||
ViewController::get()->onFileChanged(getCursor(), FILE_METADATA_CHANGED);
|
||||
|
|
Loading…
Reference in a new issue