mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 17:45:38 +00:00
Merge pull request #252 from zigurana/KidMode
UI modes part 2: Kid mode (File Filtering and system hiding)
This commit is contained in:
commit
c70acc88de
|
@ -1,4 +1,6 @@
|
||||||
#include "FileFilterIndex.h"
|
#include "FileFilterIndex.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "views/ViewController.h"
|
||||||
|
|
||||||
#include "FileData.h"
|
#include "FileData.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
@ -9,15 +11,18 @@
|
||||||
#define INCLUDE_UNKNOWN false;
|
#define INCLUDE_UNKNOWN false;
|
||||||
|
|
||||||
FileFilterIndex::FileFilterIndex()
|
FileFilterIndex::FileFilterIndex()
|
||||||
: filterByGenre(false), filterByPlayers(false), filterByPubDev(false), filterByRatings(false), filterByFavorites(false)
|
: filterByFavorites(false), filterByGenre(false), filterByHidden(false), filterByKidGame(false), filterByPlayers(false), filterByPubDev(false), filterByRatings(false)
|
||||||
{
|
{
|
||||||
|
clearAllFilters();
|
||||||
FilterDataDecl filterDecls[] = {
|
FilterDataDecl filterDecls[] = {
|
||||||
//type //allKeys //filteredBy //filteredKeys //primaryKey //hasSecondaryKey //secondaryKey //menuLabel
|
//type //allKeys //filteredBy //filteredKeys //primaryKey //hasSecondaryKey //secondaryKey //menuLabel
|
||||||
{ FAVORITES_FILTER, &favoritesIndexAllKeys, &filterByFavorites, &favoritesIndexFilteredKeys,"favorite", false, "", "FAVORITES" },
|
{ FAVORITES_FILTER, &favoritesIndexAllKeys, &filterByFavorites, &favoritesIndexFilteredKeys,"favorite", false, "", "FAVORITES" },
|
||||||
{ GENRE_FILTER, &genreIndexAllKeys, &filterByGenre, &genreIndexFilteredKeys, "genre", true, "genre", "GENRE" },
|
{ GENRE_FILTER, &genreIndexAllKeys, &filterByGenre, &genreIndexFilteredKeys, "genre", true, "genre", "GENRE" },
|
||||||
{ PLAYER_FILTER, &playersIndexAllKeys, &filterByPlayers, &playersIndexFilteredKeys, "players", false, "", "PLAYERS" },
|
{ PLAYER_FILTER, &playersIndexAllKeys, &filterByPlayers, &playersIndexFilteredKeys, "players", false, "", "PLAYERS" },
|
||||||
{ PUBDEV_FILTER, &pubDevIndexAllKeys, &filterByPubDev, &pubDevIndexFilteredKeys, "developer", true, "publisher", "PUBLISHER / DEVELOPER" },
|
{ PUBDEV_FILTER, &pubDevIndexAllKeys, &filterByPubDev, &pubDevIndexFilteredKeys, "developer", true, "publisher", "PUBLISHER / DEVELOPER" },
|
||||||
{ RATINGS_FILTER, &ratingsIndexAllKeys, &filterByRatings, &ratingsIndexFilteredKeys, "rating", false, "", "RATING" }
|
{ RATINGS_FILTER, &ratingsIndexAllKeys, &filterByRatings, &ratingsIndexFilteredKeys, "rating", false, "", "RATING" },
|
||||||
|
{ KIDGAME_FILTER, &kidGameIndexAllKeys, &filterByKidGame, &kidGameIndexFilteredKeys, "kidgame", false, "", "KIDGAME" },
|
||||||
|
{ HIDDEN_FILTER, &hiddenIndexAllKeys, &filterByHidden, &hiddenIndexFilteredKeys, "hidden", false, "", "HIDDEN" }
|
||||||
};
|
};
|
||||||
|
|
||||||
filterDataDecl = std::vector<FilterDataDecl>(filterDecls, filterDecls + sizeof(filterDecls) / sizeof(filterDecls[0]));
|
filterDataDecl = std::vector<FilterDataDecl>(filterDecls, filterDecls + sizeof(filterDecls) / sizeof(filterDecls[0]));
|
||||||
|
@ -46,7 +51,9 @@ void FileFilterIndex::importIndex(FileFilterIndex* indexToImport)
|
||||||
{ &playersIndexAllKeys, &(indexToImport->playersIndexAllKeys) },
|
{ &playersIndexAllKeys, &(indexToImport->playersIndexAllKeys) },
|
||||||
{ &pubDevIndexAllKeys, &(indexToImport->pubDevIndexAllKeys) },
|
{ &pubDevIndexAllKeys, &(indexToImport->pubDevIndexAllKeys) },
|
||||||
{ &ratingsIndexAllKeys, &(indexToImport->ratingsIndexAllKeys) },
|
{ &ratingsIndexAllKeys, &(indexToImport->ratingsIndexAllKeys) },
|
||||||
{ &favoritesIndexAllKeys, &(indexToImport->favoritesIndexAllKeys) }
|
{ &favoritesIndexAllKeys, &(indexToImport->favoritesIndexAllKeys) },
|
||||||
|
{ &hiddenIndexAllKeys, &(indexToImport->hiddenIndexAllKeys) },
|
||||||
|
{ &kidGameIndexAllKeys, &(indexToImport->kidGameIndexAllKeys) },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<IndexImportStructure> indexImportDecl = std::vector<IndexImportStructure>(indexStructDecls, indexStructDecls + sizeof(indexStructDecls) / sizeof(indexStructDecls[0]));
|
std::vector<IndexImportStructure> indexImportDecl = std::vector<IndexImportStructure>(indexStructDecls, indexStructDecls + sizeof(indexStructDecls) / sizeof(indexStructDecls[0]));
|
||||||
|
@ -75,6 +82,8 @@ void FileFilterIndex::resetIndex()
|
||||||
clearIndex(pubDevIndexAllKeys);
|
clearIndex(pubDevIndexAllKeys);
|
||||||
clearIndex(ratingsIndexAllKeys);
|
clearIndex(ratingsIndexAllKeys);
|
||||||
clearIndex(favoritesIndexAllKeys);
|
clearIndex(favoritesIndexAllKeys);
|
||||||
|
clearIndex(hiddenIndexAllKeys);
|
||||||
|
clearIndex(kidGameIndexAllKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType type, bool getSecondary)
|
std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType type, bool getSecondary)
|
||||||
|
@ -149,6 +158,20 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ
|
||||||
key = strToUpper(game->metadata.get("favorite"));
|
key = strToUpper(game->metadata.get("favorite"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case HIDDEN_FILTER:
|
||||||
|
{
|
||||||
|
if (game->getType() != GAME)
|
||||||
|
return "FALSE";
|
||||||
|
key = strToUpper(game->metadata.get("hidden"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KIDGAME_FILTER:
|
||||||
|
{
|
||||||
|
if (game->getType() != GAME)
|
||||||
|
return "FALSE";
|
||||||
|
key = strToUpper(game->metadata.get("kidgame"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
boost::trim(key);
|
boost::trim(key);
|
||||||
if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) {
|
if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) {
|
||||||
|
@ -164,6 +187,8 @@ void FileFilterIndex::addToIndex(FileData* game)
|
||||||
managePubDevEntryInIndex(game);
|
managePubDevEntryInIndex(game);
|
||||||
manageRatingsEntryInIndex(game);
|
manageRatingsEntryInIndex(game);
|
||||||
manageFavoritesEntryInIndex(game);
|
manageFavoritesEntryInIndex(game);
|
||||||
|
manageHiddenEntryInIndex(game);
|
||||||
|
manageKidGameEntryInIndex(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileFilterIndex::removeFromIndex(FileData* game)
|
void FileFilterIndex::removeFromIndex(FileData* game)
|
||||||
|
@ -173,6 +198,8 @@ void FileFilterIndex::removeFromIndex(FileData* game)
|
||||||
managePubDevEntryInIndex(game, true);
|
managePubDevEntryInIndex(game, true);
|
||||||
manageRatingsEntryInIndex(game, true);
|
manageRatingsEntryInIndex(game, true);
|
||||||
manageFavoritesEntryInIndex(game, true);
|
manageFavoritesEntryInIndex(game, true);
|
||||||
|
manageHiddenEntryInIndex(game, true);
|
||||||
|
manageKidGameEntryInIndex(game, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileFilterIndex::setFilter(FilterIndexType type, std::vector<std::string>* values)
|
void FileFilterIndex::setFilter(FilterIndexType type, std::vector<std::string>* values)
|
||||||
|
@ -213,6 +240,28 @@ void FileFilterIndex::clearAllFilters()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileFilterIndex::resetFilters()
|
||||||
|
{
|
||||||
|
clearAllFilters();
|
||||||
|
setUIModeFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileFilterIndex::setUIModeFilters()
|
||||||
|
{
|
||||||
|
if (!ViewController::get()->isUIModeFull())
|
||||||
|
{
|
||||||
|
filterByHidden = true;
|
||||||
|
std::vector<std::string> val = { "FALSE" };
|
||||||
|
setFilter(HIDDEN_FILTER, &val);
|
||||||
|
}
|
||||||
|
if (ViewController::get()->isUIModeKid())
|
||||||
|
{
|
||||||
|
filterByKidGame = true;
|
||||||
|
std::vector<std::string> val = { "TRUE" };
|
||||||
|
setFilter(KIDGAME_FILTER, &val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FileFilterIndex::debugPrintIndexes()
|
void FileFilterIndex::debugPrintIndexes()
|
||||||
{
|
{
|
||||||
LOG(LogInfo) << "Printing Indexes...";
|
LOG(LogInfo) << "Printing Indexes...";
|
||||||
|
@ -231,6 +280,12 @@ void FileFilterIndex::debugPrintIndexes()
|
||||||
for (auto x: favoritesIndexAllKeys) {
|
for (auto x: favoritesIndexAllKeys) {
|
||||||
LOG(LogInfo) << "Favorites Index: " << x.first << ": " << x.second;
|
LOG(LogInfo) << "Favorites Index: " << x.first << ": " << x.second;
|
||||||
}
|
}
|
||||||
|
for (auto x : hiddenIndexAllKeys) {
|
||||||
|
LOG(LogInfo) << "Hidden Index: " << x.first << ": " << x.second;
|
||||||
|
}
|
||||||
|
for (auto x : kidGameIndexAllKeys) {
|
||||||
|
LOG(LogInfo) << "KidGames Index: " << x.first << ": " << x.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileFilterIndex::showFile(FileData* game)
|
bool FileFilterIndex::showFile(FileData* game)
|
||||||
|
@ -290,10 +345,10 @@ bool FileFilterIndex::showFile(FileData* game)
|
||||||
|
|
||||||
bool FileFilterIndex::isKeyBeingFilteredBy(std::string key, FilterIndexType type)
|
bool FileFilterIndex::isKeyBeingFilteredBy(std::string key, FilterIndexType type)
|
||||||
{
|
{
|
||||||
const FilterIndexType filterTypes[5] = { FAVORITES_FILTER, PLAYER_FILTER, RATINGS_FILTER, GENRE_FILTER, PUBDEV_FILTER };
|
const FilterIndexType filterTypes[7] = { FAVORITES_FILTER, GENRE_FILTER, PLAYER_FILTER, PUBDEV_FILTER, RATINGS_FILTER,HIDDEN_FILTER, KIDGAME_FILTER };
|
||||||
std::vector<std::string> filterKeysList[5] = { favoritesIndexFilteredKeys, playersIndexFilteredKeys, ratingsIndexFilteredKeys, genreIndexFilteredKeys, pubDevIndexFilteredKeys };
|
std::vector<std::string> filterKeysList[7] = { favoritesIndexFilteredKeys, genreIndexFilteredKeys, playersIndexFilteredKeys, pubDevIndexFilteredKeys, ratingsIndexFilteredKeys, hiddenIndexFilteredKeys, kidGameIndexFilteredKeys };
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
if (filterTypes[i] == type)
|
if (filterTypes[i] == type)
|
||||||
{
|
{
|
||||||
|
@ -416,6 +471,32 @@ void FileFilterIndex::manageFavoritesEntryInIndex(FileData* game, bool remove)
|
||||||
manageIndexEntry(&favoritesIndexAllKeys, key, remove);
|
manageIndexEntry(&favoritesIndexAllKeys, key, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileFilterIndex::manageHiddenEntryInIndex(FileData* game, bool remove)
|
||||||
|
{
|
||||||
|
// flag for including unknowns
|
||||||
|
bool includeUnknown = INCLUDE_UNKNOWN;
|
||||||
|
std::string key = getIndexableKey(game, HIDDEN_FILTER, false);
|
||||||
|
if (!includeUnknown && key == UNKNOWN_LABEL) {
|
||||||
|
// no valid hidden info found
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manageIndexEntry(&hiddenIndexAllKeys, key, remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileFilterIndex::manageKidGameEntryInIndex(FileData* game, bool remove)
|
||||||
|
{
|
||||||
|
// flag for including unknowns
|
||||||
|
bool includeUnknown = INCLUDE_UNKNOWN;
|
||||||
|
std::string key = getIndexableKey(game, KIDGAME_FILTER, false);
|
||||||
|
if (!includeUnknown && key == UNKNOWN_LABEL) {
|
||||||
|
// no valid kidgame info found
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manageIndexEntry(&kidGameIndexAllKeys, key, remove);
|
||||||
|
}
|
||||||
|
|
||||||
void FileFilterIndex::manageIndexEntry(std::map<std::string, int>* index, std::string key, bool remove) {
|
void FileFilterIndex::manageIndexEntry(std::map<std::string, int>* index, std::string key, bool remove) {
|
||||||
bool includeUnknown = INCLUDE_UNKNOWN;
|
bool includeUnknown = INCLUDE_UNKNOWN;
|
||||||
if (!includeUnknown && key == UNKNOWN_LABEL)
|
if (!includeUnknown && key == UNKNOWN_LABEL)
|
||||||
|
|
|
@ -14,7 +14,9 @@ enum FilterIndexType
|
||||||
PLAYER_FILTER,
|
PLAYER_FILTER,
|
||||||
PUBDEV_FILTER,
|
PUBDEV_FILTER,
|
||||||
RATINGS_FILTER,
|
RATINGS_FILTER,
|
||||||
FAVORITES_FILTER
|
FAVORITES_FILTER,
|
||||||
|
HIDDEN_FILTER,
|
||||||
|
KIDGAME_FILTER
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FilterDataDecl
|
struct FilterDataDecl
|
||||||
|
@ -40,12 +42,15 @@ public:
|
||||||
void clearAllFilters();
|
void clearAllFilters();
|
||||||
void debugPrintIndexes();
|
void debugPrintIndexes();
|
||||||
bool showFile(FileData* game);
|
bool showFile(FileData* game);
|
||||||
bool isFiltered() { return (filterByGenre || filterByPlayers || filterByPubDev || filterByRatings || filterByFavorites); };
|
bool isFiltered() { return (filterByGenre || filterByPlayers || filterByPubDev || filterByRatings || filterByFavorites || filterByHidden || filterByKidGame); };
|
||||||
bool isKeyBeingFilteredBy(std::string key, FilterIndexType type);
|
bool isKeyBeingFilteredBy(std::string key, FilterIndexType type);
|
||||||
std::vector<FilterDataDecl>& getFilterDataDecls();
|
std::vector<FilterDataDecl>& getFilterDataDecls();
|
||||||
|
|
||||||
void importIndex(FileFilterIndex* indexToImport);
|
void importIndex(FileFilterIndex* indexToImport);
|
||||||
void resetIndex();
|
void resetIndex();
|
||||||
|
void resetFilters();
|
||||||
|
void setUIModeFilters();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<FilterDataDecl> filterDataDecl;
|
std::vector<FilterDataDecl> filterDataDecl;
|
||||||
std::string getIndexableKey(FileData* game, FilterIndexType type, bool getSecondary);
|
std::string getIndexableKey(FileData* game, FilterIndexType type, bool getSecondary);
|
||||||
|
@ -55,6 +60,8 @@ private:
|
||||||
void managePubDevEntryInIndex(FileData* game, bool remove = false);
|
void managePubDevEntryInIndex(FileData* game, bool remove = false);
|
||||||
void manageRatingsEntryInIndex(FileData* game, bool remove = false);
|
void manageRatingsEntryInIndex(FileData* game, bool remove = false);
|
||||||
void manageFavoritesEntryInIndex(FileData* game, bool remove = false);
|
void manageFavoritesEntryInIndex(FileData* game, bool remove = false);
|
||||||
|
void manageHiddenEntryInIndex(FileData* game, bool remove = false);
|
||||||
|
void manageKidGameEntryInIndex(FileData* game, bool remove = false);
|
||||||
|
|
||||||
void manageIndexEntry(std::map<std::string, int>* index, std::string key, bool remove);
|
void manageIndexEntry(std::map<std::string, int>* index, std::string key, bool remove);
|
||||||
|
|
||||||
|
@ -65,18 +72,24 @@ private:
|
||||||
bool filterByPubDev;
|
bool filterByPubDev;
|
||||||
bool filterByRatings;
|
bool filterByRatings;
|
||||||
bool filterByFavorites;
|
bool filterByFavorites;
|
||||||
|
bool filterByHidden;
|
||||||
|
bool filterByKidGame;
|
||||||
|
|
||||||
std::map<std::string, int> genreIndexAllKeys;
|
std::map<std::string, int> genreIndexAllKeys;
|
||||||
std::map<std::string, int> playersIndexAllKeys;
|
std::map<std::string, int> playersIndexAllKeys;
|
||||||
std::map<std::string, int> pubDevIndexAllKeys;
|
std::map<std::string, int> pubDevIndexAllKeys;
|
||||||
std::map<std::string, int> ratingsIndexAllKeys;
|
std::map<std::string, int> ratingsIndexAllKeys;
|
||||||
std::map<std::string, int> favoritesIndexAllKeys;
|
std::map<std::string, int> favoritesIndexAllKeys;
|
||||||
|
std::map<std::string, int> hiddenIndexAllKeys;
|
||||||
|
std::map<std::string, int> kidGameIndexAllKeys;
|
||||||
|
|
||||||
std::vector<std::string> genreIndexFilteredKeys;
|
std::vector<std::string> genreIndexFilteredKeys;
|
||||||
std::vector<std::string> playersIndexFilteredKeys;
|
std::vector<std::string> playersIndexFilteredKeys;
|
||||||
std::vector<std::string> pubDevIndexFilteredKeys;
|
std::vector<std::string> pubDevIndexFilteredKeys;
|
||||||
std::vector<std::string> ratingsIndexFilteredKeys;
|
std::vector<std::string> ratingsIndexFilteredKeys;
|
||||||
std::vector<std::string> favoritesIndexFilteredKeys;
|
std::vector<std::string> favoritesIndexFilteredKeys;
|
||||||
|
std::vector<std::string> hiddenIndexFilteredKeys;
|
||||||
|
std::vector<std::string> kidGameIndexFilteredKeys;
|
||||||
|
|
||||||
FileData* mRootFolder;
|
FileData* mRootFolder;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ MetaDataDecl gameDecls[] = {
|
||||||
{"genre", MD_STRING, "unknown", false, "genre", "enter game genre"},
|
{"genre", MD_STRING, "unknown", false, "genre", "enter game genre"},
|
||||||
{"players", MD_INT, "1", false, "players", "enter number of players"},
|
{"players", MD_INT, "1", false, "players", "enter number of players"},
|
||||||
{"favorite", MD_BOOL, "false", false, "favorite", "enter favorite off/on"},
|
{"favorite", MD_BOOL, "false", false, "favorite", "enter favorite off/on"},
|
||||||
|
{"hidden", MD_BOOL, "false", false, "hidden", "enter hidden off/on" },
|
||||||
|
{"kidgame", MD_BOOL, "false", false, "kidgame", "enter kidgame off/on" },
|
||||||
{"playcount", MD_INT, "0", true, "play count", "enter number of times played"},
|
{"playcount", MD_INT, "0", true, "play count", "enter number of times played"},
|
||||||
{"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"}
|
{"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"}
|
||||||
};
|
};
|
||||||
|
|
|
@ -340,6 +340,33 @@ std::string SystemData::getConfigPath(bool forWrite)
|
||||||
return "/etc/emulationstation/es_systems.cfg";
|
return "/etc/emulationstation/es_systems.cfg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemData* SystemData::getNext() const
|
||||||
|
{
|
||||||
|
std::vector<SystemData*>::const_iterator it = getIterator();
|
||||||
|
|
||||||
|
do {
|
||||||
|
it++;
|
||||||
|
if (it == sSystemVector.end())
|
||||||
|
it = sSystemVector.begin();
|
||||||
|
} while ((*it)->getDisplayedGameCount() == 0);
|
||||||
|
// as we are starting in a valid gamelistview, this will always succeed, even if we have to come full circle.
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemData* SystemData::getPrev() const
|
||||||
|
{
|
||||||
|
auto it = getRevIterator();
|
||||||
|
do {
|
||||||
|
it++;
|
||||||
|
if (it == sSystemVector.rend())
|
||||||
|
it = sSystemVector.rbegin();
|
||||||
|
} while ((*it)->getDisplayedGameCount() == 0);
|
||||||
|
// as we are starting in a valid gamelistview, this will always succeed, even if we have to come full circle.
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
std::string SystemData::getGamelistPath(bool forWrite) const
|
std::string SystemData::getGamelistPath(bool forWrite) const
|
||||||
{
|
{
|
||||||
fs::path filePath;
|
fs::path filePath;
|
||||||
|
|
|
@ -56,22 +56,9 @@ public:
|
||||||
inline std::vector<SystemData*>::const_reverse_iterator getRevIterator() const { return std::find(sSystemVector.rbegin(), sSystemVector.rend(), this); };
|
inline std::vector<SystemData*>::const_reverse_iterator getRevIterator() const { return std::find(sSystemVector.rbegin(), sSystemVector.rend(), this); };
|
||||||
inline bool isCollection() { return mIsCollectionSystem; };
|
inline bool isCollection() { return mIsCollectionSystem; };
|
||||||
inline bool isGameSystem() { return mIsGameSystem; }
|
inline bool isGameSystem() { return mIsGameSystem; }
|
||||||
inline SystemData* getNext() const
|
|
||||||
{
|
|
||||||
auto it = getIterator();
|
|
||||||
it++;
|
|
||||||
if(it == sSystemVector.end()) it = sSystemVector.begin();
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SystemData* getPrev() const
|
|
||||||
{
|
|
||||||
auto it = getRevIterator();
|
|
||||||
it++;
|
|
||||||
if(it == sSystemVector.rend()) it = sSystemVector.rbegin();
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SystemData* getNext() const;
|
||||||
|
SystemData* getPrev() const;
|
||||||
static SystemData* getRandomSystem();
|
static SystemData* getRandomSystem();
|
||||||
FileData* getRandomGame();
|
FileData* getRandomGame();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "guis/GuiGamelistFilter.h"
|
#include "guis/GuiGamelistFilter.h"
|
||||||
|
|
||||||
#include "components/OptionListComponent.h"
|
#include "components/OptionListComponent.h"
|
||||||
|
#include "views/ViewController.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
|
|
||||||
GuiGamelistFilter::GuiGamelistFilter(Window* window, SystemData* system) : GuiComponent(window), mMenu(window, "FILTER GAMELIST BY"), mSystem(system)
|
GuiGamelistFilter::GuiGamelistFilter(Window* window, SystemData* system) : GuiComponent(window), mMenu(window, "FILTER GAMELIST BY"), mSystem(system)
|
||||||
|
@ -34,7 +35,7 @@ void GuiGamelistFilter::initializeMenu()
|
||||||
|
|
||||||
void GuiGamelistFilter::resetAllFilters()
|
void GuiGamelistFilter::resetAllFilters()
|
||||||
{
|
{
|
||||||
mFilterIndex->clearAllFilters();
|
mFilterIndex->resetFilters();
|
||||||
for (std::map<FilterIndexType, std::shared_ptr< OptionListComponent<std::string> >>::iterator it = mFilterOptions.begin(); it != mFilterOptions.end(); ++it ) {
|
for (std::map<FilterIndexType, std::shared_ptr< OptionListComponent<std::string> >>::iterator it = mFilterOptions.begin(); it != mFilterOptions.end(); ++it ) {
|
||||||
std::shared_ptr< OptionListComponent<std::string> > optionList = it->second;
|
std::shared_ptr< OptionListComponent<std::string> > optionList = it->second;
|
||||||
optionList->selectNone();
|
optionList->selectNone();
|
||||||
|
@ -49,7 +50,14 @@ GuiGamelistFilter::~GuiGamelistFilter()
|
||||||
void GuiGamelistFilter::addFiltersToMenu()
|
void GuiGamelistFilter::addFiltersToMenu()
|
||||||
{
|
{
|
||||||
std::vector<FilterDataDecl> decls = mFilterIndex->getFilterDataDecls();
|
std::vector<FilterDataDecl> decls = mFilterIndex->getFilterDataDecls();
|
||||||
for (std::vector<FilterDataDecl>::iterator it = decls.begin(); it != decls.end(); ++it ) {
|
|
||||||
|
int skip = 0;
|
||||||
|
if (!ViewController::get()->isUIModeFull())
|
||||||
|
skip = 1;
|
||||||
|
if (ViewController::get()->isUIModeKid())
|
||||||
|
skip = 2;
|
||||||
|
|
||||||
|
for (std::vector<FilterDataDecl>::iterator it = decls.begin(); it != decls.end()-skip; ++it ) {
|
||||||
|
|
||||||
FilterIndexType type = (*it).type; // type of filter
|
FilterIndexType type = (*it).type; // type of filter
|
||||||
std::map<std::string, int>* allKeys = (*it).allIndexKeys; // all possible filters for this type
|
std::map<std::string, int>* allKeys = (*it).allIndexKeys; // all possible filters for this type
|
||||||
|
|
|
@ -38,6 +38,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
||||||
if (isFullUI)
|
if (isFullUI)
|
||||||
addEntry("CONFIGURE INPUT", 0x777777FF, true, [this] { openConfigInput(); });
|
addEntry("CONFIGURE INPUT", 0x777777FF, true, [this] { openConfigInput(); });
|
||||||
|
|
||||||
|
if (!(ViewController::get()->isUIModeKid() && Settings::getInstance()->getBool("hideQuitMenuOnKidUI")))
|
||||||
addEntry("QUIT", 0x777777FF, true, [this] {openQuitMenu(); });
|
addEntry("QUIT", 0x777777FF, true, [this] {openQuitMenu(); });
|
||||||
|
|
||||||
addChild(&mMenu);
|
addChild(&mMenu);
|
||||||
|
@ -422,12 +423,11 @@ void GuiMenu::openQuitMenu()
|
||||||
s->addRow(row);
|
s->addRow(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row.elements.clear();
|
row.elements.clear();
|
||||||
row.makeAcceptInputHandler([window] {
|
row.makeAcceptInputHandler([window] {
|
||||||
window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
|
window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
|
||||||
[] {
|
[] {
|
||||||
if(quitES("/tmp/es-sysrestart") != 0)
|
if (quitES("/tmp/es-sysrestart") != 0)
|
||||||
LOG(LogWarning) << "Restart terminated with non-zero result!";
|
LOG(LogWarning) << "Restart terminated with non-zero result!";
|
||||||
}, "NO", nullptr));
|
}, "NO", nullptr));
|
||||||
});
|
});
|
||||||
|
@ -455,7 +455,6 @@ void GuiMenu::addVersionInfo()
|
||||||
mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING));
|
mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING));
|
||||||
mVersion.setHorizontalAlignment(ALIGN_CENTER);
|
mVersion.setHorizontalAlignment(ALIGN_CENTER);
|
||||||
addChild(&mVersion);
|
addChild(&mVersion);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiMenu::openScreensaverOptions() {
|
void GuiMenu::openScreensaverOptions() {
|
||||||
|
|
|
@ -86,7 +86,12 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height
|
||||||
else if (strcmp(argv[i], "--force-kiosk") == 0)
|
else if (strcmp(argv[i], "--force-kiosk") == 0)
|
||||||
{
|
{
|
||||||
Settings::getInstance()->setBool("ForceKiosk", true);
|
Settings::getInstance()->setBool("ForceKiosk", true);
|
||||||
}else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
|
}
|
||||||
|
else if (strcmp(argv[i], "--force-kid") == 0)
|
||||||
|
{
|
||||||
|
Settings::getInstance()->setBool("ForceKid", true);
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// This is a bit of a hack, but otherwise output will go to nowhere
|
// This is a bit of a hack, but otherwise output will go to nowhere
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "views/SystemView.h"
|
#include "views/SystemView.h"
|
||||||
|
|
||||||
#include "animations/LambdaAnimation.h"
|
#include "animations/LambdaAnimation.h"
|
||||||
|
#include "guis/GuiMsgBox.h"
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
@ -35,6 +36,8 @@ void SystemView::populate()
|
||||||
if(mViewNeedsReload)
|
if(mViewNeedsReload)
|
||||||
getViewElements(theme);
|
getViewElements(theme);
|
||||||
|
|
||||||
|
if((*it)->getDisplayedGameCount() > 0)
|
||||||
|
{
|
||||||
Entry e;
|
Entry e;
|
||||||
e.name = (*it)->getName();
|
e.name = (*it)->getName();
|
||||||
e.object = *it;
|
e.object = *it;
|
||||||
|
@ -51,7 +54,6 @@ void SystemView::populate()
|
||||||
ImageComponent* logo = new ImageComponent(mWindow, false, false);
|
ImageComponent* logo = new ImageComponent(mWindow, false, false);
|
||||||
logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
|
logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
|
||||||
logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
|
logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
|
||||||
|
|
||||||
e.data.logo = std::shared_ptr<GuiComponent>(logo);
|
e.data.logo = std::shared_ptr<GuiComponent>(logo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +94,6 @@ void SystemView::populate()
|
||||||
|
|
||||||
Vector2f denormalized = mCarousel.logoSize * e.data.logo->getOrigin();
|
Vector2f denormalized = mCarousel.logoSize * e.data.logo->getOrigin();
|
||||||
e.data.logo->setPosition(denormalized.x(), denormalized.y(), 0.0);
|
e.data.logo->setPosition(denormalized.x(), denormalized.y(), 0.0);
|
||||||
|
|
||||||
// delete any existing extras
|
// delete any existing extras
|
||||||
for (auto extra : e.data.backgroundExtras)
|
for (auto extra : e.data.backgroundExtras)
|
||||||
delete extra;
|
delete extra;
|
||||||
|
@ -108,6 +109,16 @@ void SystemView::populate()
|
||||||
|
|
||||||
this->add(e);
|
this->add(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (mEntries.size() == 0)
|
||||||
|
{
|
||||||
|
// Something is wrong, there is not a single system to show, check if UI mode is not full
|
||||||
|
if (!ViewController::get()->isUIModeFull())
|
||||||
|
{
|
||||||
|
Settings::getInstance()->setString("UIMode", "Full");
|
||||||
|
mWindow->pushGui(new GuiMsgBox(mWindow, "The selected UI mode has nothing to show,\n returning to UI mode: FULL", "OK", nullptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemView::goToSystem(SystemData* system, bool animate)
|
void SystemView::goToSystem(SystemData* system, bool animate)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "views/gamelist/IGameListView.h"
|
#include "views/gamelist/IGameListView.h"
|
||||||
#include "views/gamelist/VideoGameListView.h"
|
#include "views/gamelist/VideoGameListView.h"
|
||||||
#include "views/SystemView.h"
|
#include "views/SystemView.h"
|
||||||
|
#include "FileFilterIndex.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
|
@ -411,6 +412,7 @@ void ViewController::preload()
|
||||||
{
|
{
|
||||||
for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
|
for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
|
||||||
{
|
{
|
||||||
|
(*it)->getIndex()->resetFilters();
|
||||||
getGameListView(*it);
|
getGameListView(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +450,7 @@ void ViewController::reloadGameListView(IGameListView* view, bool reloadTheme)
|
||||||
|
|
||||||
void ViewController::reloadAll()
|
void ViewController::reloadAll()
|
||||||
{
|
{
|
||||||
|
// clear all gamelistviews
|
||||||
std::map<SystemData*, FileData*> cursorMap;
|
std::map<SystemData*, FileData*> cursorMap;
|
||||||
for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++)
|
for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++)
|
||||||
{
|
{
|
||||||
|
@ -455,12 +458,16 @@ void ViewController::reloadAll()
|
||||||
}
|
}
|
||||||
mGameListViews.clear();
|
mGameListViews.clear();
|
||||||
|
|
||||||
|
|
||||||
|
// load themes, create gamelistviews and reset filters
|
||||||
for(auto it = cursorMap.begin(); it != cursorMap.end(); it++)
|
for(auto it = cursorMap.begin(); it != cursorMap.end(); it++)
|
||||||
{
|
{
|
||||||
it->first->loadTheme();
|
it->first->loadTheme();
|
||||||
|
it->first->getIndex()->resetFilters();
|
||||||
getGameListView(it->first)->setCursor(it->second);
|
getGameListView(it->first)->setCursor(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuild SystemListView
|
||||||
mSystemListView.reset();
|
mSystemListView.reset();
|
||||||
getSystemListView();
|
getSystemListView();
|
||||||
|
|
||||||
|
@ -486,6 +493,7 @@ void ViewController::monitorUIMode()
|
||||||
std::string uimode = Settings::getInstance()->getString("UIMode");
|
std::string uimode = Settings::getInstance()->getString("UIMode");
|
||||||
if (uimode != mCurUIMode) // UIMODE HAS CHANGED
|
if (uimode != mCurUIMode) // UIMODE HAS CHANGED
|
||||||
{
|
{
|
||||||
|
mWindow->renderLoadingScreen();
|
||||||
mCurUIMode = uimode;
|
mCurUIMode = uimode;
|
||||||
reloadAll();
|
reloadAll();
|
||||||
goToStart();
|
goToStart();
|
||||||
|
@ -497,6 +505,12 @@ bool ViewController::isUIModeFull()
|
||||||
return ((mCurUIMode == "Full") && ! Settings::getInstance()->getBool("ForceKiosk"));
|
return ((mCurUIMode == "Full") && ! Settings::getInstance()->getBool("ForceKiosk"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ViewController::isUIModeKid()
|
||||||
|
{
|
||||||
|
return (Settings::getInstance()->getBool("ForceKid") ||
|
||||||
|
((mCurUIMode == "Kid") && !Settings::getInstance()->getBool("ForceKiosk")));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<HelpPrompt> ViewController::getHelpPrompts()
|
std::vector<HelpPrompt> ViewController::getHelpPrompts()
|
||||||
{
|
{
|
||||||
std::vector<HelpPrompt> prompts;
|
std::vector<HelpPrompt> prompts;
|
||||||
|
|
|
@ -11,7 +11,7 @@ class IGameListView;
|
||||||
class SystemData;
|
class SystemData;
|
||||||
class SystemView;
|
class SystemView;
|
||||||
|
|
||||||
const std::vector<std::string> UIModes = { "Full", "Kiosk" };
|
const std::vector<std::string> UIModes = { "Full", "Kiosk", "Kid" };
|
||||||
|
|
||||||
// Used to smoothly transition the camera between multiple views (e.g. from system to system, from gamelist to gamelist).
|
// Used to smoothly transition the camera between multiple views (e.g. from system to system, from gamelist to gamelist).
|
||||||
class ViewController : public GuiComponent
|
class ViewController : public GuiComponent
|
||||||
|
@ -33,8 +33,9 @@ public:
|
||||||
void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes.
|
void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes.
|
||||||
|
|
||||||
void monitorUIMode();
|
void monitorUIMode();
|
||||||
bool isUIModeFull();
|
|
||||||
inline std::vector<std::string> getUIModes() { return UIModes; };
|
inline std::vector<std::string> getUIModes() { return UIModes; };
|
||||||
|
bool isUIModeFull();
|
||||||
|
bool isUIModeKid();
|
||||||
|
|
||||||
// Navigation.
|
// Navigation.
|
||||||
void goToNextGameList();
|
void goToNextGameList();
|
||||||
|
|
|
@ -141,7 +141,7 @@ std::vector<HelpPrompt> BasicGameListView::getHelpPrompts()
|
||||||
prompts.push_back(HelpPrompt("b", "back"));
|
prompts.push_back(HelpPrompt("b", "back"));
|
||||||
prompts.push_back(HelpPrompt("select", "options"));
|
prompts.push_back(HelpPrompt("select", "options"));
|
||||||
prompts.push_back(HelpPrompt("x", "random"));
|
prompts.push_back(HelpPrompt("x", "random"));
|
||||||
if(mRoot->getSystem()->isGameSystem())
|
if(mRoot->getSystem()->isGameSystem() && !ViewController::get()->isUIModeKid())
|
||||||
{
|
{
|
||||||
std::string prompt = CollectionSystemManager::get()->getEditingCollection();
|
std::string prompt = CollectionSystemManager::get()->getEditingCollection();
|
||||||
prompts.push_back(HelpPrompt("y", prompt));
|
prompts.push_back(HelpPrompt("y", prompt));
|
||||||
|
|
|
@ -142,7 +142,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
|
||||||
setCursor(randomGame);
|
setCursor(randomGame);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}else if (config->isMappedTo("y", input))
|
}else if (config->isMappedTo("y", input) && !(ViewController::get()->isUIModeKid()))
|
||||||
{
|
{
|
||||||
if(mRoot->getSystem()->isGameSystem())
|
if(mRoot->getSystem()->isGameSystem())
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@ std::vector<const char*> settings_dont_save = boost::assign::list_of
|
||||||
("Debug")
|
("Debug")
|
||||||
("DebugGrid")
|
("DebugGrid")
|
||||||
("DebugText")
|
("DebugText")
|
||||||
|
("ForceKid")
|
||||||
("ForceKiosk")
|
("ForceKiosk")
|
||||||
("IgnoreGamelist")
|
("IgnoreGamelist")
|
||||||
("HideConsole")
|
("HideConsole")
|
||||||
|
@ -124,6 +125,8 @@ void Settings::setDefaults()
|
||||||
mStringMap["UIMode"] = "Full";
|
mStringMap["UIMode"] = "Full";
|
||||||
mStringMap["UIMode_passkey"] = "uuddlrlrba";
|
mStringMap["UIMode_passkey"] = "uuddlrlrba";
|
||||||
mBoolMap["ForceKiosk"] = false;
|
mBoolMap["ForceKiosk"] = false;
|
||||||
|
mBoolMap["ForceKid"] = false;
|
||||||
|
mBoolMap["hideQuitMenuOnKidUI"] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V>
|
||||||
|
|
Loading…
Reference in a new issue