mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 17:45:38 +00:00
Support sorting of game list via input
You can now map the functions "sortordernext" and "sortorderprevious" to inputs (in es_input.cfg) and toggle the game list sort order with them. The order is: "file name, ascending" (default), "file name, descending", "rating ascending", "rating descending", "user rating ascending", "user rating descending", "time played ascending", "times played descending", "last played time ascending", "last played time descending".
This commit is contained in:
parent
c61a470694
commit
a60fe463d4
|
@ -4,6 +4,9 @@
|
|||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
std::map<FolderData::ComparisonFunction*, std::string> FolderData::sortStateNameMap;
|
||||
|
||||
bool FolderData::isFolder() const { return true; }
|
||||
const std::string & FolderData::getName() const { return mName; }
|
||||
const std::string & FolderData::getPath() const { return mPath; }
|
||||
|
@ -11,10 +14,16 @@ unsigned int FolderData::getFileCount() { return mFileVector.size(); }
|
|||
|
||||
|
||||
FolderData::FolderData(SystemData* system, std::string path, std::string name)
|
||||
: mSystem(system), mPath(path), mName(name)
|
||||
{
|
||||
mSystem = system;
|
||||
mPath = path;
|
||||
mName = name;
|
||||
//first created folder data initializes the list
|
||||
if (sortStateNameMap.empty()) {
|
||||
sortStateNameMap[compareFileName] = "file name";
|
||||
sortStateNameMap[compareRating] = "rating";
|
||||
sortStateNameMap[compareUserRating] = "user rating";
|
||||
sortStateNameMap[compareTimesPlayed] = "times played";
|
||||
sortStateNameMap[compareLastPlayed] = "last time played";
|
||||
}
|
||||
}
|
||||
|
||||
FolderData::~FolderData()
|
||||
|
@ -32,6 +41,22 @@ void FolderData::pushFileData(FileData* file)
|
|||
mFileVector.push_back(file);
|
||||
}
|
||||
|
||||
//sort this folder and any subfolders
|
||||
void FolderData::sort(ComparisonFunction & comparisonFunction, bool ascending)
|
||||
{
|
||||
std::sort(mFileVector.begin(), mFileVector.end(), comparisonFunction);
|
||||
|
||||
for(unsigned int i = 0; i < mFileVector.size(); i++)
|
||||
{
|
||||
if(mFileVector.at(i)->isFolder())
|
||||
((FolderData*)mFileVector.at(i))->sort(comparisonFunction, ascending);
|
||||
}
|
||||
|
||||
if (!ascending) {
|
||||
std::reverse(mFileVector.begin(), mFileVector.end());
|
||||
}
|
||||
}
|
||||
|
||||
//returns if file1 should come before file2
|
||||
bool FolderData::compareFileName(const FileData* file1, const FileData* file2)
|
||||
{
|
||||
|
@ -95,16 +120,16 @@ bool FolderData::compareLastPlayed(const FileData* file1, const FileData* file2)
|
|||
return false;
|
||||
}
|
||||
|
||||
//sort this folder and any subfolders
|
||||
void FolderData::sort()
|
||||
std::string FolderData::getSortStateName(ComparisonFunction & comparisonFunction, bool ascending)
|
||||
{
|
||||
std::sort(mFileVector.begin(), mFileVector.end(), compareFileName);
|
||||
|
||||
for(unsigned int i = 0; i < mFileVector.size(); i++)
|
||||
{
|
||||
if(mFileVector.at(i)->isFolder())
|
||||
((FolderData*)mFileVector.at(i))->sort();
|
||||
std::string temp = sortStateNameMap[comparisonFunction];
|
||||
if (ascending) {
|
||||
temp.append(" (ascending)");
|
||||
}
|
||||
else {
|
||||
temp.append(" (descending)");
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
FileData* FolderData::getFile(unsigned int i) const
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
#ifndef _FOLDER_H_
|
||||
#define _FOLDER_H_
|
||||
|
||||
#include "FileData.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "FileData.h"
|
||||
|
||||
|
||||
class SystemData;
|
||||
|
||||
//This class lets us hold a vector of FileDatas within under a common name.
|
||||
class FolderData : public FileData
|
||||
{
|
||||
public:
|
||||
typedef bool ComparisonFunction(const FileData* a, const FileData* b);
|
||||
struct SortState
|
||||
{
|
||||
ComparisonFunction & comparisonFunction;
|
||||
bool ascending;
|
||||
|
||||
SortState(ComparisonFunction & sortFunction, bool sortAscending) : comparisonFunction(sortFunction), ascending(sortAscending) {}
|
||||
};
|
||||
|
||||
private:
|
||||
static std::map<ComparisonFunction*, std::string> sortStateNameMap;
|
||||
|
||||
public:
|
||||
FolderData(SystemData* system, std::string path, std::string name);
|
||||
~FolderData();
|
||||
|
@ -24,13 +40,14 @@ public:
|
|||
|
||||
void pushFileData(FileData* file);
|
||||
|
||||
void sort();
|
||||
|
||||
void sort(ComparisonFunction & comparisonFunction = compareFileName, bool ascending = true);
|
||||
static bool compareFileName(const FileData* file1, const FileData* file2);
|
||||
static bool compareRating(const FileData* file1, const FileData* file2);
|
||||
static bool compareUserRating(const FileData* file1, const FileData* file2);
|
||||
static bool compareTimesPlayed(const FileData* file1, const FileData* file2);
|
||||
static bool compareLastPlayed(const FileData* file1, const FileData* file2);
|
||||
static std::string getSortStateName(ComparisonFunction & comparisonFunction = compareFileName, bool ascending = true);
|
||||
|
||||
private:
|
||||
SystemData* mSystem;
|
||||
std::string mPath;
|
||||
|
|
|
@ -404,6 +404,9 @@ void InputManager::loadDefaultConfig()
|
|||
|
||||
cfg->mapInput("mastervolup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_PLUS, 1, true));
|
||||
cfg->mapInput("mastervoldown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_MINUS, 1, true));
|
||||
|
||||
cfg->mapInput("sortordernext", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F7, 1, true));
|
||||
cfg->mapInput("sortorderprevious", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F8, 1, true));
|
||||
}
|
||||
|
||||
void InputManager::writeConfig()
|
||||
|
|
|
@ -7,15 +7,31 @@
|
|||
#include "../Log.h"
|
||||
#include "../Settings.h"
|
||||
|
||||
|
||||
std::vector<FolderData::SortState> GuiGameList::sortStates;
|
||||
|
||||
|
||||
Vector2i GuiGameList::getImagePos()
|
||||
{
|
||||
return Vector2i((int)(Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX")), (int)(Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY")));
|
||||
}
|
||||
|
||||
GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window),
|
||||
mDescription(window), mTransitionImage(window, 0, 0, "", Renderer::getScreenWidth(), Renderer::getScreenHeight(), true)
|
||||
mDescription(window), mTransitionImage(window, 0, 0, "", Renderer::getScreenWidth(), Renderer::getScreenHeight(), true), mDetailed(useDetail), sortStateIndex(0)
|
||||
{
|
||||
mDetailed = useDetail;
|
||||
//first object initializes the vector
|
||||
if (sortStates.empty()) {
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareFileName, true));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareFileName, false));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareRating, true));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareRating, false));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareUserRating, true));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareUserRating, false));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareTimesPlayed, true));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareTimesPlayed, false));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareLastPlayed, true));
|
||||
sortStates.push_back(FolderData::SortState(FolderData::compareLastPlayed, false));
|
||||
}
|
||||
|
||||
mTheme = new ThemeComponent(mWindow, mDetailed);
|
||||
|
||||
|
@ -190,6 +206,16 @@ bool GuiGameList::input(InputConfig* config, Input input)
|
|||
}
|
||||
}
|
||||
|
||||
//change sort order
|
||||
if(config->isMappedTo("sortordernext", input) && input.value != 0) {
|
||||
setNextSortIndex();
|
||||
//std::cout << "Sort order is " << FolderData::getSortStateName(sortStates.at(sortStateIndex).comparisonFunction, sortStates.at(sortStateIndex).ascending) << std::endl;
|
||||
}
|
||||
else if(config->isMappedTo("sortorderprevious", input) && input.value != 0) {
|
||||
setPreviousSortIndex();
|
||||
//std::cout << "Sort order is " << FolderData::getSortStateName(sortStates.at(sortStateIndex).comparisonFunction, sortStates.at(sortStateIndex).ascending) << std::endl;
|
||||
}
|
||||
|
||||
//open the "start menu"
|
||||
if(config->isMappedTo("menu", input) && input.value != 0)
|
||||
{
|
||||
|
@ -219,6 +245,45 @@ bool GuiGameList::input(InputConfig* config, Input input)
|
|||
return false;
|
||||
}
|
||||
|
||||
void GuiGameList::setSortIndex(size_t index)
|
||||
{
|
||||
//make the index valid
|
||||
if (index >= sortStates.size()) {
|
||||
index = 0;
|
||||
}
|
||||
if (index != sortStateIndex) {
|
||||
//get sort state from vector and sort list
|
||||
sortStateIndex = index;
|
||||
sort(sortStates.at(sortStateIndex).comparisonFunction, sortStates.at(sortStateIndex).ascending);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameList::setNextSortIndex()
|
||||
{
|
||||
//make the index wrap around
|
||||
if ((sortStateIndex - 1) >= sortStates.size()) {
|
||||
setSortIndex(0);
|
||||
}
|
||||
setSortIndex(sortStateIndex + 1);
|
||||
}
|
||||
|
||||
void GuiGameList::setPreviousSortIndex()
|
||||
{
|
||||
//make the index wrap around
|
||||
if (((int)sortStateIndex - 1) < 0) {
|
||||
setSortIndex(sortStates.size() - 1);
|
||||
}
|
||||
setSortIndex(sortStateIndex - 1);
|
||||
}
|
||||
|
||||
void GuiGameList::sort(FolderData::ComparisonFunction & comparisonFunction, bool ascending)
|
||||
{
|
||||
//resort list and update it
|
||||
mFolder->sort(comparisonFunction, ascending);
|
||||
updateList();
|
||||
updateDetailData();
|
||||
}
|
||||
|
||||
void GuiGameList::updateList()
|
||||
{
|
||||
if(mDetailed)
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
//It has a TextListComponent child that handles the game list, a ThemeComponent that handles the theming system, and an ImageComponent for game images.
|
||||
class GuiGameList : public GuiComponent
|
||||
{
|
||||
static std::vector<FolderData::SortState> sortStates;
|
||||
size_t sortStateIndex;
|
||||
|
||||
public:
|
||||
GuiGameList(Window* window, bool useDetail = false);
|
||||
virtual ~GuiGameList();
|
||||
|
@ -32,6 +35,11 @@ public:
|
|||
|
||||
void updateDetailData();
|
||||
|
||||
void setSortIndex(size_t index);
|
||||
void setNextSortIndex();
|
||||
void setPreviousSortIndex();
|
||||
void sort(FolderData::ComparisonFunction & comparisonFunction = FolderData::compareFileName, bool ascending = true);
|
||||
|
||||
static GuiGameList* create(Window* window);
|
||||
|
||||
static const float sInfoWidth;
|
||||
|
|
Loading…
Reference in a new issue