mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-26 08:05:38 +00:00
Fixed lots of code formatting issues.
This commit is contained in:
parent
a928142d5b
commit
f6dd49071e
|
@ -377,21 +377,21 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection
|
||||||
// If the countasgame flag has been set to false, then remove the game.
|
// If the countasgame flag has been set to false, then remove the game.
|
||||||
if (curSys->isGroupedCustomCollection()) {
|
if (curSys->isGroupedCustomCollection()) {
|
||||||
ViewController::get()
|
ViewController::get()
|
||||||
->getGameListView(curSys->getRootFolder()->getParent()->getSystem())
|
->getGameListView(curSys->getRootFolder()->getParent()->getSystem())
|
||||||
.get()
|
.get()
|
||||||
->remove(collectionEntry, false);
|
->remove(collectionEntry, false);
|
||||||
FileData *parentRootFolder =
|
FileData* parentRootFolder =
|
||||||
rootFolder->getParent()->getSystem()->getRootFolder();
|
rootFolder->getParent()->getSystem()->getRootFolder();
|
||||||
parentRootFolder->sort(parentRootFolder->getSortTypeFromString(
|
parentRootFolder->sort(parentRootFolder->getSortTypeFromString(
|
||||||
parentRootFolder->getSortTypeString()),
|
parentRootFolder->getSortTypeString()),
|
||||||
mFavoritesSorting);
|
mFavoritesSorting);
|
||||||
GuiInfoPopup *s = new GuiInfoPopup(
|
GuiInfoPopup* s = new GuiInfoPopup(
|
||||||
mWindow,
|
mWindow,
|
||||||
"DISABLED '" +
|
"DISABLED '" +
|
||||||
Utils::String::toUpper(
|
Utils::String::toUpper(
|
||||||
Utils::String::removeParenthesis(file->getName())) +
|
Utils::String::removeParenthesis(file->getName())) +
|
||||||
"' IN '" + Utils::String::toUpper(sysData.system->getName()) + "'",
|
"' IN '" + Utils::String::toUpper(sysData.system->getName()) + "'",
|
||||||
4000);
|
4000);
|
||||||
mWindow->setInfoPopup(s);
|
mWindow->setInfoPopup(s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -550,26 +550,28 @@ bool CollectionSystemsManager::isThemeCustomCollectionCompatible(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CollectionSystemsManager::getValidNewCollectionName(std::string inName, int index) {
|
std::string CollectionSystemsManager::getValidNewCollectionName(std::string inName, int index)
|
||||||
|
{
|
||||||
std::string name = inName;
|
std::string name = inName;
|
||||||
|
|
||||||
// Trim leading and trailing whitespaces.
|
// Trim leading and trailing whitespaces.
|
||||||
name.erase(name.begin(), std::find_if(name.begin(), name.end(), [](char c) {
|
name.erase(name.begin(), std::find_if(name.begin(), name.end(), [](char c) {
|
||||||
return !std::isspace(static_cast<unsigned char>(c));
|
return !std::isspace(static_cast<unsigned char>(c));
|
||||||
}));
|
}));
|
||||||
name.erase(std::find_if(name.rbegin(), name.rend(),
|
name.erase(std::find_if(name.rbegin(), name.rend(),
|
||||||
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
||||||
.base(),
|
.base(),
|
||||||
name.end());
|
name.end());
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
size_t remove = std::string::npos;
|
size_t remove = std::string::npos;
|
||||||
// Get valid name.
|
// Get valid name.
|
||||||
while ((remove = name.find_first_not_of(
|
while ((remove = name.find_first_not_of(
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-[]()' ")) !=
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-[]()' ")) !=
|
||||||
std::string::npos)
|
std::string::npos)
|
||||||
name.erase(remove, 1);
|
name.erase(remove, 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
name += " (" + std::to_string(index) + ")";
|
name += " (" + std::to_string(index) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1331,7 +1333,8 @@ void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CollectionSystemsManager::getSystemsFromConfig() {
|
std::vector<std::string> CollectionSystemsManager::getSystemsFromConfig()
|
||||||
|
{
|
||||||
std::vector<std::string> systems;
|
std::vector<std::string> systems;
|
||||||
std::vector<std::string> configPaths = SystemData::getConfigPath(false);
|
std::vector<std::string> configPaths = SystemData::getConfigPath(false);
|
||||||
|
|
||||||
|
@ -1339,7 +1342,7 @@ std::vector<std::string> CollectionSystemsManager::getSystemsFromConfig() {
|
||||||
// file under ~/.emulationstation/custom_systems as we really want to include all the themes
|
// file under ~/.emulationstation/custom_systems as we really want to include all the themes
|
||||||
// supported by ES-DE. Otherwise a user may accidentally create a custom collection that
|
// supported by ES-DE. Otherwise a user may accidentally create a custom collection that
|
||||||
// corresponds to a supported theme.
|
// corresponds to a supported theme.
|
||||||
for (auto path: configPaths) {
|
for (auto path : configPaths) {
|
||||||
if (!Utils::FileSystem::exists(path))
|
if (!Utils::FileSystem::exists(path))
|
||||||
return systems;
|
return systems;
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,18 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
FileData::FileData(FileType type,
|
FileData::FileData(FileType type,
|
||||||
const std::string &path,
|
const std::string& path,
|
||||||
SystemEnvironmentData *envData,
|
SystemEnvironmentData* envData,
|
||||||
SystemData *system)
|
SystemData* system)
|
||||||
: metadata(type == GAME ? GAME_METADATA : FOLDER_METADATA), mSourceFileData(nullptr), mParent(nullptr),
|
: metadata(type == GAME ? GAME_METADATA : FOLDER_METADATA)
|
||||||
mType(type), mPath(path), mEnvData(envData), mSystem(system), mOnlyFolders(false), mDeletionFlag(false)
|
, mSourceFileData(nullptr)
|
||||||
|
, mParent(nullptr)
|
||||||
|
, mType(type)
|
||||||
|
, mPath(path)
|
||||||
|
, mEnvData(envData)
|
||||||
|
, mSystem(system)
|
||||||
|
, mOnlyFolders(false)
|
||||||
|
, mDeletionFlag(false)
|
||||||
{
|
{
|
||||||
// Metadata needs at least a name field (since that's what getName() will return).
|
// Metadata needs at least a name field (since that's what getName() will return).
|
||||||
if (metadata.get("name").empty()) {
|
if (metadata.get("name").empty()) {
|
||||||
|
@ -735,10 +742,11 @@ FileData::SortType FileData::getSortTypeFromString(std::string desc)
|
||||||
return FileSorts::SortTypes.at(0);
|
return FileSorts::SortTypes.at(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileData::launchGame(Window *window) {
|
void FileData::launchGame(Window* window)
|
||||||
|
{
|
||||||
LOG(LogInfo) << "Launching game \"" << this->metadata.get("name") << "\"...";
|
LOG(LogInfo) << "Launching game \"" << this->metadata.get("name") << "\"...";
|
||||||
|
|
||||||
SystemData *gameSystem = nullptr;
|
SystemData* gameSystem = nullptr;
|
||||||
std::string command = "";
|
std::string command = "";
|
||||||
std::string alternativeEmulator;
|
std::string alternativeEmulator;
|
||||||
|
|
||||||
|
@ -1347,8 +1355,8 @@ const std::string& CollectionFileData::getName()
|
||||||
if (mDirty) {
|
if (mDirty) {
|
||||||
mCollectionFileName = mSourceFileData->metadata.get("name");
|
mCollectionFileName = mSourceFileData->metadata.get("name");
|
||||||
mCollectionFileName.append(" [")
|
mCollectionFileName.append(" [")
|
||||||
.append(Utils::String::toUpper(mSourceFileData->getSystem()->getName()))
|
.append(Utils::String::toUpper(mSourceFileData->getSystem()->getName()))
|
||||||
.append("]");
|
.append("]");
|
||||||
mDirty = false;
|
mDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,17 @@
|
||||||
#define INCLUDE_UNKNOWN false;
|
#define INCLUDE_UNKNOWN false;
|
||||||
|
|
||||||
FileFilterIndex::FileFilterIndex()
|
FileFilterIndex::FileFilterIndex()
|
||||||
: mFilterByText(false), mTextRemoveSystem(false), mFilterByFavorites(false), mFilterByGenre(false),
|
: mFilterByText(false)
|
||||||
mFilterByPlayers(false), mFilterByPubDev(false), mFilterByRatings(false), mFilterByKidGame(false),
|
, mTextRemoveSystem(false)
|
||||||
mFilterByCompleted(false), mFilterByBroken(false), mFilterByHidden(false)
|
, mFilterByFavorites(false)
|
||||||
|
, mFilterByGenre(false)
|
||||||
|
, mFilterByPlayers(false)
|
||||||
|
, mFilterByPubDev(false)
|
||||||
|
, mFilterByRatings(false)
|
||||||
|
, mFilterByKidGame(false)
|
||||||
|
, mFilterByCompleted(false)
|
||||||
|
, mFilterByBroken(false)
|
||||||
|
, mFilterByHidden(false)
|
||||||
{
|
{
|
||||||
clearAllFilters();
|
clearAllFilters();
|
||||||
|
|
||||||
|
@ -357,10 +365,11 @@ bool FileFilterIndex::showFile(FileData* game)
|
||||||
// in [] from the search string.
|
// in [] from the search string.
|
||||||
if (mTextFilter != "" && mTextRemoveSystem &&
|
if (mTextFilter != "" && mTextRemoveSystem &&
|
||||||
!(Utils::String::toUpper(game->getName().substr(0, game->getName().find_last_of("[")))
|
!(Utils::String::toUpper(game->getName().substr(0, game->getName().find_last_of("[")))
|
||||||
.find(mTextFilter) != std::string::npos)) {
|
.find(mTextFilter) != std::string::npos)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (mTextFilter != "" &&
|
}
|
||||||
!(Utils::String::toUpper(game->getName()).find(mTextFilter) != std::string::npos)) {
|
else if (mTextFilter != "" &&
|
||||||
|
!(Utils::String::toUpper(game->getName()).find(mTextFilter) != std::string::npos)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +381,8 @@ bool FileFilterIndex::showFile(FileData* game)
|
||||||
FilterDataDecl filterData = (*it);
|
FilterDataDecl filterData = (*it);
|
||||||
if (filterData.primaryKey == "kidgame" && UIModeController::getInstance()->isUIModeKid()) {
|
if (filterData.primaryKey == "kidgame" && UIModeController::getInstance()->isUIModeKid()) {
|
||||||
return (getIndexableKey(game, filterData.type, false) != "FALSE");
|
return (getIndexableKey(game, filterData.type, false) != "FALSE");
|
||||||
} else if (*(filterData.filteredByRef)) {
|
}
|
||||||
|
else if (*(filterData.filteredByRef)) {
|
||||||
// Try to find a match.
|
// Try to find a match.
|
||||||
std::string key = getIndexableKey(game, filterData.type, false);
|
std::string key = getIndexableKey(game, filterData.type, false);
|
||||||
keepGoing = isKeyBeingFilteredBy(key, filterData.type);
|
keepGoing = isKeyBeingFilteredBy(key, filterData.type);
|
||||||
|
|
|
@ -49,11 +49,11 @@ public:
|
||||||
FileFilterIndex();
|
FileFilterIndex();
|
||||||
~FileFilterIndex();
|
~FileFilterIndex();
|
||||||
|
|
||||||
void addToIndex(FileData *game);
|
void addToIndex(FileData* game);
|
||||||
|
|
||||||
void removeFromIndex(FileData *game);
|
void removeFromIndex(FileData* game);
|
||||||
|
|
||||||
void setFilter(FilterIndexType type, std::vector<std::string> *values);
|
void setFilter(FilterIndexType type, std::vector<std::string>* values);
|
||||||
|
|
||||||
void setTextFilter(std::string textFilter);
|
void setTextFilter(std::string textFilter);
|
||||||
|
|
||||||
|
@ -63,17 +63,17 @@ public:
|
||||||
|
|
||||||
void debugPrintIndexes();
|
void debugPrintIndexes();
|
||||||
|
|
||||||
bool showFile(FileData *game);
|
bool showFile(FileData* game);
|
||||||
|
|
||||||
bool isFiltered();
|
bool isFiltered();
|
||||||
|
|
||||||
bool isKeyBeingFilteredBy(std::string key, FilterIndexType type);
|
bool isKeyBeingFilteredBy(std::string key, FilterIndexType type);
|
||||||
|
|
||||||
std::vector<FilterDataDecl> &getFilterDataDecls() { return filterDataDecl; }
|
std::vector<FilterDataDecl>& getFilterDataDecls() { return filterDataDecl; }
|
||||||
|
|
||||||
void setTextRemoveSystem(bool status) { mTextRemoveSystem = status; }
|
void setTextRemoveSystem(bool status) { mTextRemoveSystem = status; }
|
||||||
|
|
||||||
void importIndex(FileFilterIndex *indexToImport);
|
void importIndex(FileFilterIndex* indexToImport);
|
||||||
|
|
||||||
void resetIndex();
|
void resetIndex();
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,8 @@ namespace FileSorts
|
||||||
return system1.compare(system2) < 0;
|
return system1.compare(system2) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compareSystemDescending(const FileData *file1, const FileData *file2) {
|
bool compareSystemDescending(const FileData* file1, const FileData* file2)
|
||||||
|
{
|
||||||
std::string system1 = Utils::String::toUpper(file1->getSystemName());
|
std::string system1 = Utils::String::toUpper(file1->getSystemName());
|
||||||
std::string system2 = Utils::String::toUpper(file2->getSystemName());
|
std::string system2 = Utils::String::toUpper(file2->getSystemName());
|
||||||
return system1.compare(system2) > 0;
|
return system1.compare(system2) > 0;
|
||||||
|
|
|
@ -19,41 +19,41 @@ namespace FileSorts
|
||||||
bool compareName(const FileData* file1, const FileData* file2);
|
bool compareName(const FileData* file1, const FileData* file2);
|
||||||
bool compareNameDescending(const FileData* file1, const FileData* file2);
|
bool compareNameDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareRating(const FileData *file1, const FileData *file2);
|
bool compareRating(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareRatingDescending(const FileData *file1, const FileData *file2);
|
bool compareRatingDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareReleaseDate(const FileData *file1, const FileData *file2);
|
bool compareReleaseDate(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareReleaseDateDescending(const FileData *file1, const FileData *file2);
|
bool compareReleaseDateDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareDeveloper(const FileData *file1, const FileData *file2);
|
bool compareDeveloper(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareDeveloperDescending(const FileData *file1, const FileData *file2);
|
bool compareDeveloperDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool comparePublisher(const FileData *file1, const FileData *file2);
|
bool comparePublisher(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool comparePublisherDescending(const FileData *file1, const FileData *file2);
|
bool comparePublisherDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareGenre(const FileData *file1, const FileData *file2);
|
bool compareGenre(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareGenreDescending(const FileData *file1, const FileData *file2);
|
bool compareGenreDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareNumPlayers(const FileData *file1, const FileData *file2);
|
bool compareNumPlayers(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareNumPlayersDescending(const FileData *file1, const FileData *file2);
|
bool compareNumPlayersDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareLastPlayed(const FileData *file1, const FileData *file2);
|
bool compareLastPlayed(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareLastPlayedDescending(const FileData *file1, const FileData *file2);
|
bool compareLastPlayedDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareTimesPlayed(const FileData *file1, const FileData *fil2);
|
bool compareTimesPlayed(const FileData* file1, const FileData* fil2);
|
||||||
|
|
||||||
bool compareTimesPlayedDescending(const FileData *file1, const FileData *fil2);
|
bool compareTimesPlayedDescending(const FileData* file1, const FileData* fil2);
|
||||||
|
|
||||||
bool compareSystem(const FileData *file1, const FileData *file2);
|
bool compareSystem(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
bool compareSystemDescending(const FileData *file1, const FileData *file2);
|
bool compareSystemDescending(const FileData* file1, const FileData* file2);
|
||||||
|
|
||||||
extern const std::vector<FileData::SortType> SortTypes;
|
extern const std::vector<FileData::SortType> SortTypes;
|
||||||
} // namespace FileSorts
|
} // namespace FileSorts
|
||||||
|
|
|
@ -200,12 +200,12 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
|
||||||
glm::vec2{0.0f, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()});
|
glm::vec2{0.0f, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()});
|
||||||
row.addElement(newCollection, true);
|
row.addElement(newCollection, true);
|
||||||
row.addElement(bracketNewCollection, false);
|
row.addElement(bracketNewCollection, false);
|
||||||
auto createCollectionCall = [this](const std::string &newVal) {
|
auto createCollectionCall = [this](const std::string& newVal) {
|
||||||
std::string name = newVal;
|
std::string name = newVal;
|
||||||
// We need to store the first GUI and remove it, as it'll be deleted
|
// We need to store the first GUI and remove it, as it'll be deleted
|
||||||
// by the actual GUI.
|
// by the actual GUI.
|
||||||
Window *window = mWindow;
|
Window* window = mWindow;
|
||||||
GuiComponent *topGui = window->peekGui();
|
GuiComponent* topGui = window->peekGui();
|
||||||
window->removeGui(topGui);
|
window->removeGui(topGui);
|
||||||
createCustomCollection(name);
|
createCustomCollection(name);
|
||||||
};
|
};
|
||||||
|
@ -213,10 +213,11 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
|
||||||
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
||||||
row.makeAcceptInputHandler([this, createCollectionCall] {
|
row.makeAcceptInputHandler([this, createCollectionCall] {
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
||||||
mWindow, getHelpStyle(), "New Collection Name", "", createCollectionCall, false,
|
mWindow, getHelpStyle(), "New Collection Name", "", createCollectionCall, false,
|
||||||
"CREATE", "CREATE COLLECTION?"));
|
"CREATE", "CREATE COLLECTION?"));
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
row.makeAcceptInputHandler([this, createCollectionCall] {
|
row.makeAcceptInputHandler([this, createCollectionCall] {
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "New Collection Name",
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "New Collection Name",
|
||||||
"", createCollectionCall, false, "CREATE",
|
"", createCollectionCall, false, "CREATE",
|
||||||
|
@ -228,11 +229,11 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
|
||||||
// Delete custom collection.
|
// Delete custom collection.
|
||||||
row.elements.clear();
|
row.elements.clear();
|
||||||
auto deleteCollection = std::make_shared<TextComponent>(
|
auto deleteCollection = std::make_shared<TextComponent>(
|
||||||
mWindow, "DELETE CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
mWindow, "DELETE CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
||||||
auto bracketDeleteCollection = std::make_shared<ImageComponent>(mWindow);
|
auto bracketDeleteCollection = std::make_shared<ImageComponent>(mWindow);
|
||||||
bracketDeleteCollection->setImage(":/graphics/arrow.svg");
|
bracketDeleteCollection->setImage(":/graphics/arrow.svg");
|
||||||
bracketDeleteCollection->setResize(
|
bracketDeleteCollection->setResize(
|
||||||
glm::vec2{0.0f, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()});
|
glm::vec2{0.0f, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()});
|
||||||
row.addElement(deleteCollection, true);
|
row.addElement(deleteCollection, true);
|
||||||
row.addElement(bracketDeleteCollection, false);
|
row.addElement(bracketDeleteCollection, false);
|
||||||
row.makeAcceptInputHandler([this, customSystems] {
|
row.makeAcceptInputHandler([this, customSystems] {
|
||||||
|
|
|
@ -18,11 +18,14 @@
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
|
|
||||||
GuiGameScraper::GuiGameScraper(Window *window,
|
GuiGameScraper::GuiGameScraper(Window* window,
|
||||||
ScraperSearchParams params,
|
ScraperSearchParams params,
|
||||||
std::function<void(const ScraperSearchResult &)> doneFunc)
|
std::function<void(const ScraperSearchResult&)> doneFunc)
|
||||||
: GuiComponent(window), mClose(false), mGrid(window, glm::ivec2{1, 7}), mBox(window, ":/graphics/frame.svg"),
|
: GuiComponent(window)
|
||||||
mSearchParams(params)
|
, mClose(false)
|
||||||
|
, mGrid(window, glm::ivec2{1, 7})
|
||||||
|
, mBox(window, ":/graphics/frame.svg")
|
||||||
|
, mSearchParams(params)
|
||||||
{
|
{
|
||||||
addChild(&mBox);
|
addChild(&mBox);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
|
|
@ -29,7 +29,8 @@ GuiGamelistFilter::GuiGamelistFilter(Window* window,
|
||||||
initializeMenu();
|
initializeMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiGamelistFilter::initializeMenu() {
|
void GuiGamelistFilter::initializeMenu()
|
||||||
|
{
|
||||||
addChild(&mMenu);
|
addChild(&mMenu);
|
||||||
|
|
||||||
// Get filters from system.
|
// Get filters from system.
|
||||||
|
@ -93,12 +94,13 @@ void GuiGamelistFilter::resetAllFilters()
|
||||||
|
|
||||||
GuiGamelistFilter::~GuiGamelistFilter() { mFilterOptions.clear(); }
|
GuiGamelistFilter::~GuiGamelistFilter() { mFilterOptions.clear(); }
|
||||||
|
|
||||||
void GuiGamelistFilter::addFiltersToMenu() {
|
void GuiGamelistFilter::addFiltersToMenu()
|
||||||
|
{
|
||||||
ComponentListRow row;
|
ComponentListRow row;
|
||||||
|
|
||||||
auto lbl = std::make_shared<TextComponent>(
|
auto lbl = std::make_shared<TextComponent>(
|
||||||
mWindow, Utils::String::toUpper(ViewController::KEYBOARD_CHAR + " GAME NAME"),
|
mWindow, Utils::String::toUpper(ViewController::KEYBOARD_CHAR + " GAME NAME"),
|
||||||
Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
||||||
|
|
||||||
mTextFilterField = std::make_shared<TextComponent>(mWindow, "", Font::get(FONT_SIZE_MEDIUM),
|
mTextFilterField = std::make_shared<TextComponent>(mWindow, "", Font::get(FONT_SIZE_MEDIUM),
|
||||||
0x777777FF, ALIGN_RIGHT);
|
0x777777FF, ALIGN_RIGHT);
|
||||||
|
@ -121,7 +123,7 @@ void GuiGamelistFilter::addFiltersToMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback function.
|
// Callback function.
|
||||||
auto updateVal = [this](const std::string &newVal) {
|
auto updateVal = [this](const std::string& newVal) {
|
||||||
mTextFilterField->setValue(Utils::String::toUpper(newVal));
|
mTextFilterField->setValue(Utils::String::toUpper(newVal));
|
||||||
mFilterIndex->setTextFilter(Utils::String::toUpper(newVal));
|
mFilterIndex->setTextFilter(Utils::String::toUpper(newVal));
|
||||||
};
|
};
|
||||||
|
@ -132,7 +134,8 @@ void GuiGamelistFilter::addFiltersToMenu() {
|
||||||
mTextFilterField->getValue(), updateVal,
|
mTextFilterField->getValue(), updateVal,
|
||||||
false, "OK", "APPLY CHANGES?"));
|
false, "OK", "APPLY CHANGES?"));
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
row.makeAcceptInputHandler([this, updateVal] {
|
row.makeAcceptInputHandler([this, updateVal] {
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "GAME NAME",
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "GAME NAME",
|
||||||
mTextFilterField->getValue(), updateVal, false,
|
mTextFilterField->getValue(), updateVal, false,
|
||||||
|
|
|
@ -25,9 +25,15 @@
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
#include "views/gamelist/IGameListView.h"
|
#include "views/gamelist/IGameListView.h"
|
||||||
|
|
||||||
GuiGamelistOptions::GuiGamelistOptions(Window *window, SystemData *system)
|
GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system)
|
||||||
: GuiComponent(window), mMenu(window, "OPTIONS"), mSystem(system), mFiltersChanged(false), mCancelled(false),
|
: GuiComponent(window)
|
||||||
mIsCustomCollection(false), mIsCustomCollectionGroup(false), mCustomCollectionSystem(nullptr)
|
, mMenu(window, "OPTIONS")
|
||||||
|
, mSystem(system)
|
||||||
|
, mFiltersChanged(false)
|
||||||
|
, mCancelled(false)
|
||||||
|
, mIsCustomCollection(false)
|
||||||
|
, mIsCustomCollectionGroup(false)
|
||||||
|
, mCustomCollectionSystem(nullptr)
|
||||||
{
|
{
|
||||||
addChild(&mMenu);
|
addChild(&mMenu);
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,12 @@
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
|
||||||
GuiLaunchScreen::GuiLaunchScreen(Window *window)
|
GuiLaunchScreen::GuiLaunchScreen(Window* window)
|
||||||
: GuiComponent(window), mWindow(window), mBackground(window, ":/graphics/frame.svg"), mGrid(nullptr),
|
: GuiComponent(window)
|
||||||
mMarquee(nullptr)
|
, mWindow(window)
|
||||||
|
, mBackground(window, ":/graphics/frame.svg")
|
||||||
|
, mGrid(nullptr)
|
||||||
|
, mMarquee(nullptr)
|
||||||
{
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
mWindow->setLaunchScreen(this);
|
mWindow->setLaunchScreen(this);
|
||||||
|
@ -217,7 +220,8 @@ void GuiLaunchScreen::update(int deltaTime)
|
||||||
mScaleUp = glm::clamp(mScaleUp + 0.07f, 0.0f, 1.0f);
|
mScaleUp = glm::clamp(mScaleUp + 0.07f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiLaunchScreen::render(const glm::mat4 & /*parentTrans*/) {
|
void GuiLaunchScreen::render(const glm::mat4& /*parentTrans*/)
|
||||||
|
{
|
||||||
// Scale up animation.
|
// Scale up animation.
|
||||||
if (mScaleUp < 1.0f)
|
if (mScaleUp < 1.0f)
|
||||||
setScale(mScaleUp);
|
setScale(mScaleUp);
|
||||||
|
|
|
@ -21,11 +21,11 @@ class FileData;
|
||||||
class GuiLaunchScreen : public Window::GuiLaunchScreen, GuiComponent
|
class GuiLaunchScreen : public Window::GuiLaunchScreen, GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiLaunchScreen(Window *window);
|
GuiLaunchScreen(Window* window);
|
||||||
|
|
||||||
virtual ~GuiLaunchScreen();
|
virtual ~GuiLaunchScreen();
|
||||||
|
|
||||||
virtual void displayLaunchScreen(FileData *game) override;
|
virtual void displayLaunchScreen(FileData* game) override;
|
||||||
|
|
||||||
virtual void closeLaunchScreen() override;
|
virtual void closeLaunchScreen() override;
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ public:
|
||||||
|
|
||||||
virtual void update(int deltaTime) override;
|
virtual void update(int deltaTime) override;
|
||||||
|
|
||||||
virtual void render(const glm::mat4 &parentTrans) override;
|
virtual void render(const glm::mat4& parentTrans) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window *mWindow;
|
Window* mWindow;
|
||||||
NinePatchComponent mBackground;
|
NinePatchComponent mBackground;
|
||||||
ComponentGrid *mGrid;
|
ComponentGrid* mGrid;
|
||||||
|
|
||||||
std::shared_ptr<TextComponent> mTitle;
|
std::shared_ptr<TextComponent> mTitle;
|
||||||
std::shared_ptr<TextComponent> mGameName;
|
std::shared_ptr<TextComponent> mGameName;
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
GuiMenu::GuiMenu(Window *window)
|
GuiMenu::GuiMenu(Window* window)
|
||||||
: GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window)
|
: GuiComponent(window)
|
||||||
|
, mMenu(window, "MAIN MENU")
|
||||||
|
, mVersion(window)
|
||||||
{
|
{
|
||||||
bool isFullUI = UIModeController::getInstance()->isUIModeFull();
|
bool isFullUI = UIModeController::getInstance()->isUIModeFull();
|
||||||
|
|
||||||
|
@ -822,16 +824,17 @@ void GuiMenu::openOtherOptions()
|
||||||
multiLineMediaDir] {
|
multiLineMediaDir] {
|
||||||
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
||||||
mWindow, getHelpStyle(), titleMediaDir,
|
mWindow, getHelpStyle(), titleMediaDir,
|
||||||
Settings::getInstance()->getString("MediaDirectory"), updateValMediaDir,
|
Settings::getInstance()->getString("MediaDirectory"), updateValMediaDir,
|
||||||
multiLineMediaDir, "SAVE", "SAVE CHANGES?", mediaDirectoryStaticText,
|
multiLineMediaDir, "SAVE", "SAVE CHANGES?", mediaDirectoryStaticText,
|
||||||
defaultDirectoryText, "load default directory"));
|
defaultDirectoryText, "load default directory"));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mWindow->pushGui(new GuiTextEditPopup(
|
mWindow->pushGui(new GuiTextEditPopup(
|
||||||
mWindow, getHelpStyle(), titleMediaDir,
|
mWindow, getHelpStyle(), titleMediaDir,
|
||||||
Settings::getInstance()->getString("MediaDirectory"), updateValMediaDir,
|
Settings::getInstance()->getString("MediaDirectory"), updateValMediaDir,
|
||||||
multiLineMediaDir, "SAVE", "SAVE CHANGES?", mediaDirectoryStaticText,
|
multiLineMediaDir, "SAVE", "SAVE CHANGES?", mediaDirectoryStaticText,
|
||||||
defaultDirectoryText, "load default directory"));
|
defaultDirectoryText, "load default directory"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
s->addRow(rowMediaDir);
|
s->addRow(rowMediaDir);
|
||||||
|
|
|
@ -31,18 +31,25 @@
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
|
|
||||||
GuiMetaDataEd::GuiMetaDataEd(Window *window,
|
GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
MetaDataList *md,
|
MetaDataList* md,
|
||||||
const std::vector<MetaDataDecl> &mdd,
|
const std::vector<MetaDataDecl>& mdd,
|
||||||
ScraperSearchParams scraperParams,
|
ScraperSearchParams scraperParams,
|
||||||
const std::string & /*header*/,
|
const std::string& /*header*/,
|
||||||
std::function<void()> saveCallback,
|
std::function<void()> saveCallback,
|
||||||
std::function<void()> clearGameFunc,
|
std::function<void()> clearGameFunc,
|
||||||
std::function<void()> deleteGameFunc)
|
std::function<void()> deleteGameFunc)
|
||||||
: GuiComponent(window), mBackground(window, ":/graphics/frame.svg"), mGrid(window, glm::ivec2{1, 3}),
|
: GuiComponent(window)
|
||||||
mScraperParams(scraperParams), mMetaDataDecl(mdd), mMetaData(md), mSavedCallback(saveCallback),
|
, mBackground(window, ":/graphics/frame.svg")
|
||||||
mClearGameFunc(clearGameFunc), mDeleteGameFunc(deleteGameFunc), mMediaFilesUpdated(false),
|
, mGrid(window, glm::ivec2{1, 3})
|
||||||
mInvalidEmulatorEntry(false)
|
, mScraperParams(scraperParams)
|
||||||
|
, mMetaDataDecl(mdd)
|
||||||
|
, mMetaData(md)
|
||||||
|
, mSavedCallback(saveCallback)
|
||||||
|
, mClearGameFunc(clearGameFunc)
|
||||||
|
, mDeleteGameFunc(deleteGameFunc)
|
||||||
|
, mMediaFilesUpdated(false)
|
||||||
|
, mInvalidEmulatorEntry(false)
|
||||||
{
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
@ -211,11 +218,11 @@ GuiMetaDataEd::GuiMetaDataEd(Window *window,
|
||||||
if (mInvalidEmulatorEntry ||
|
if (mInvalidEmulatorEntry ||
|
||||||
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() > 1) {
|
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() > 1) {
|
||||||
row.makeAcceptInputHandler([this, title, scraperParams, ed, updateVal,
|
row.makeAcceptInputHandler([this, title, scraperParams, ed, updateVal,
|
||||||
originalValue] {
|
originalValue] {
|
||||||
GuiSettings *s = nullptr;
|
GuiSettings* s = nullptr;
|
||||||
|
|
||||||
bool singleEntry =
|
bool singleEntry =
|
||||||
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() == 1;
|
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() == 1;
|
||||||
|
|
||||||
if (mInvalidEmulatorEntry && singleEntry)
|
if (mInvalidEmulatorEntry && singleEntry)
|
||||||
s = new GuiSettings(mWindow, "CLEAR INVALID ENTRY");
|
s = new GuiSettings(mWindow, "CLEAR INVALID ENTRY");
|
||||||
|
@ -226,16 +233,16 @@ GuiMetaDataEd::GuiMetaDataEd(Window *window,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> launchCommands =
|
std::vector<std::pair<std::string, std::string>> launchCommands =
|
||||||
scraperParams.system->getSystemEnvData()->mLaunchCommands;
|
scraperParams.system->getSystemEnvData()->mLaunchCommands;
|
||||||
|
|
||||||
if (ed->getValue() != "" && mInvalidEmulatorEntry && singleEntry)
|
if (ed->getValue() != "" && mInvalidEmulatorEntry && singleEntry)
|
||||||
launchCommands.push_back(std::make_pair(
|
launchCommands.push_back(std::make_pair(
|
||||||
"", ViewController::EXCLAMATION_CHAR + " " + originalValue));
|
"", ViewController::EXCLAMATION_CHAR + " " + originalValue));
|
||||||
else if (ed->getValue() != "")
|
else if (ed->getValue() != "")
|
||||||
launchCommands.push_back(std::make_pair(
|
launchCommands.push_back(std::make_pair(
|
||||||
"", ViewController::CROSSEDCIRCLE_CHAR + " CLEAR ENTRY"));
|
"", ViewController::CROSSEDCIRCLE_CHAR + " CLEAR ENTRY"));
|
||||||
|
|
||||||
for (auto entry: launchCommands) {
|
for (auto entry : launchCommands) {
|
||||||
std::string selectedLabel = ed->getValue();
|
std::string selectedLabel = ed->getValue();
|
||||||
std::string label;
|
std::string label;
|
||||||
ComponentListRow row;
|
ComponentListRow row;
|
||||||
|
@ -356,7 +363,8 @@ GuiMetaDataEd::GuiMetaDataEd(Window *window,
|
||||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||||
else
|
else
|
||||||
ed->setColor(TEXTCOLOR_USERMARKED);
|
ed->setColor(TEXTCOLOR_USERMARKED);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ed->setValue(newVal);
|
ed->setValue(newVal);
|
||||||
if (newVal == originalValue)
|
if (newVal == originalValue)
|
||||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||||
|
@ -368,10 +376,11 @@ GuiMetaDataEd::GuiMetaDataEd(Window *window,
|
||||||
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
if (Settings::getInstance()->getBool("VirtualKeyboard")) {
|
||||||
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
||||||
mWindow, getHelpStyle(), title, ed->getValue(), updateVal, multiLine,
|
mWindow, getHelpStyle(), title, ed->getValue(), updateVal, multiLine,
|
||||||
"apply", "APPLY CHANGES?", "", ""));
|
"apply", "APPLY CHANGES?", "", ""));
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), title,
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), title,
|
||||||
ed->getValue(), updateVal, multiLine,
|
ed->getValue(), updateVal, multiLine,
|
||||||
|
|
|
@ -13,9 +13,11 @@
|
||||||
#include "components/MenuComponent.h"
|
#include "components/MenuComponent.h"
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
|
|
||||||
GuiOfflineGenerator::GuiOfflineGenerator(Window *window, const std::queue<FileData *> &gameQueue)
|
GuiOfflineGenerator::GuiOfflineGenerator(Window* window, const std::queue<FileData*>& gameQueue)
|
||||||
: GuiComponent(window), mGameQueue(gameQueue), mBackground(window, ":/graphics/frame.svg"),
|
: GuiComponent(window)
|
||||||
mGrid(window, glm::ivec2{6, 13})
|
, mGameQueue(gameQueue)
|
||||||
|
, mBackground(window, ":/graphics/frame.svg")
|
||||||
|
, mGrid(window, glm::ivec2{6, 13})
|
||||||
{
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
|
|
@ -86,19 +86,19 @@ GuiScraperMulti::GuiScraperMulti(Window* window,
|
||||||
// Previously refined.
|
// Previously refined.
|
||||||
if (mSearchComp->getRefinedSearch())
|
if (mSearchComp->getRefinedSearch())
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Interactive mode and "Auto-accept single game matches" not enabled.
|
// Interactive mode and "Auto-accept single game matches" not enabled.
|
||||||
else if (mSearchComp->getSearchType() !=
|
else if (mSearchComp->getSearchType() !=
|
||||||
GuiScraperSearch::ACCEPT_SINGLE_MATCHES)
|
GuiScraperSearch::ACCEPT_SINGLE_MATCHES)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Interactive mode with "Auto-accept single game matches" enabled and more
|
// Interactive mode with "Auto-accept single game matches" enabled and more
|
||||||
// than one result.
|
// than one result.
|
||||||
else if (mSearchComp->getSearchType() ==
|
else if (mSearchComp->getSearchType() ==
|
||||||
GuiScraperSearch::ACCEPT_SINGLE_MATCHES &&
|
GuiScraperSearch::ACCEPT_SINGLE_MATCHES &&
|
||||||
mSearchComp->getScraperResultsSize() > 1)
|
mSearchComp->getScraperResultsSize() > 1)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Dito but there were no games found, or the search has not been completed.
|
// Dito but there were no games found, or the search has not been completed.
|
||||||
else if (mSearchComp->getSearchType() ==
|
else if (mSearchComp->getSearchType() ==
|
||||||
GuiScraperSearch::ACCEPT_SINGLE_MATCHES &&
|
GuiScraperSearch::ACCEPT_SINGLE_MATCHES &&
|
||||||
!mSearchComp->getFoundGame())
|
!mSearchComp->getFoundGame())
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,15 @@
|
||||||
|
|
||||||
#define FAILED_VERIFICATION_RETRIES 8
|
#define FAILED_VERIFICATION_RETRIES 8
|
||||||
|
|
||||||
GuiScraperSearch::GuiScraperSearch(Window *window, SearchType type, unsigned int scrapeCount)
|
GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int scrapeCount)
|
||||||
: GuiComponent(window), mGrid(window, glm::ivec2{4, 3}), mSearchType(type), mScrapeCount(scrapeCount),
|
: GuiComponent(window)
|
||||||
mRefinedSearch(false), mFoundGame(false), mScrapeRatings(false), mBusyAnim(window)
|
, mGrid(window, glm::ivec2{4, 3})
|
||||||
|
, mSearchType(type)
|
||||||
|
, mScrapeCount(scrapeCount)
|
||||||
|
, mRefinedSearch(false)
|
||||||
|
, mFoundGame(false)
|
||||||
|
, mScrapeRatings(false)
|
||||||
|
, mBusyAnim(window)
|
||||||
{
|
{
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
|
||||||
|
@ -467,14 +473,14 @@ void GuiScraperSearch::updateInfoPane()
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (i != -1 && static_cast<int>(mScraperResults.size()) > i) {
|
if (i != -1 && static_cast<int>(mScraperResults.size()) > i) {
|
||||||
ScraperSearchResult &res = mScraperResults.at(i);
|
ScraperSearchResult& res = mScraperResults.at(i);
|
||||||
|
|
||||||
mResultName->setText(Utils::String::toUpper(res.mdl.get("name")));
|
mResultName->setText(Utils::String::toUpper(res.mdl.get("name")));
|
||||||
mResultDesc->setText(Utils::String::toUpper(res.mdl.get("desc")));
|
mResultDesc->setText(Utils::String::toUpper(res.mdl.get("desc")));
|
||||||
mDescContainer->reset();
|
mDescContainer->reset();
|
||||||
|
|
||||||
mResultThumbnail->setImage("");
|
mResultThumbnail->setImage("");
|
||||||
const std::string &thumb = res.screenshotUrl.empty() ? res.coverUrl : res.screenshotUrl;
|
const std::string& thumb = res.screenshotUrl.empty() ? res.coverUrl : res.screenshotUrl;
|
||||||
mScraperResults[i].thumbnailImageUrl = thumb;
|
mScraperResults[i].thumbnailImageUrl = thumb;
|
||||||
|
|
||||||
// Cache the thumbnail image in mScraperResults so that we don't need to download
|
// Cache the thumbnail image in mScraperResults so that we don't need to download
|
||||||
|
@ -547,13 +553,13 @@ bool GuiScraperSearch::input(InputConfig* config, Input input)
|
||||||
// Previously refined.
|
// Previously refined.
|
||||||
if (mRefinedSearch)
|
if (mRefinedSearch)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Interactive mode and "Auto-accept single game matches" not enabled.
|
// Interactive mode and "Auto-accept single game matches" not enabled.
|
||||||
else if (mSearchType != ACCEPT_SINGLE_MATCHES)
|
else if (mSearchType != ACCEPT_SINGLE_MATCHES)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Interactive mode with "Auto-accept single game matches" enabled and more than one result.
|
// Interactive mode with "Auto-accept single game matches" enabled and more than one result.
|
||||||
else if (mSearchType == ACCEPT_SINGLE_MATCHES && mScraperResults.size() > 1)
|
else if (mSearchType == ACCEPT_SINGLE_MATCHES && mScraperResults.size() > 1)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
// Dito but there were no games found, or the search has not been completed.
|
// Dito but there were no games found, or the search has not been completed.
|
||||||
else if (mSearchType == ACCEPT_SINGLE_MATCHES && !mFoundGame)
|
else if (mSearchType == ACCEPT_SINGLE_MATCHES && !mFoundGame)
|
||||||
allowRefine = true;
|
allowRefine = true;
|
||||||
|
|
||||||
|
@ -784,15 +790,16 @@ void GuiScraperSearch::updateThumbnail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiScraperSearch::openInputScreen(ScraperSearchParams ¶ms) {
|
void GuiScraperSearch::openInputScreen(ScraperSearchParams& params)
|
||||||
|
{
|
||||||
auto searchForFunc = [&](std::string name) {
|
auto searchForFunc = [&](std::string name) {
|
||||||
// Trim leading and trailing whitespaces.
|
// Trim leading and trailing whitespaces.
|
||||||
name.erase(name.begin(), std::find_if(name.begin(), name.end(), [](char c) {
|
name.erase(name.begin(), std::find_if(name.begin(), name.end(), [](char c) {
|
||||||
return !std::isspace(static_cast<unsigned char>(c));
|
return !std::isspace(static_cast<unsigned char>(c));
|
||||||
}));
|
}));
|
||||||
name.erase(std::find_if(name.rbegin(), name.rend(),
|
name.erase(std::find_if(name.rbegin(), name.rend(),
|
||||||
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
||||||
.base(),
|
.base(),
|
||||||
name.end());
|
name.end());
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
|
@ -810,7 +817,8 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams ¶ms) {
|
||||||
// regardless of whether the entry is an arcade game and TheGamesDB is used.
|
// regardless of whether the entry is an arcade game and TheGamesDB is used.
|
||||||
if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
|
if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
|
||||||
searchString = Utils::String::removeParenthesis(params.game->metadata.get("name"));
|
searchString = Utils::String::removeParenthesis(params.game->metadata.get("name"));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If searching based on the actual file name, then expand to the full game name
|
// If searching based on the actual file name, then expand to the full game name
|
||||||
// in case the scraper is set to TheGamesDB and it's an arcade game. This is
|
// in case the scraper is set to TheGamesDB and it's an arcade game. This is
|
||||||
// required as TheGamesDB does not support searches using the short MAME names.
|
// required as TheGamesDB does not support searches using the short MAME names.
|
||||||
|
@ -820,7 +828,8 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams ¶ms) {
|
||||||
else
|
else
|
||||||
searchString = params.game->getCleanName();
|
searchString = params.game->getCleanName();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
searchString = params.nameOverride;
|
searchString = params.nameOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,7 +837,8 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams ¶ms) {
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(mWindow, getHelpStyle(), "REFINE SEARCH",
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(mWindow, getHelpStyle(), "REFINE SEARCH",
|
||||||
searchString, searchForFunc, false, "SEARCH",
|
searchString, searchForFunc, false, "SEARCH",
|
||||||
"SEARCH USING REFINED NAME?"));
|
"SEARCH USING REFINED NAME?"));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "REFINE SEARCH",
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "REFINE SEARCH",
|
||||||
searchString, searchForFunc, false, "SEARCH",
|
searchString, searchForFunc, false, "SEARCH",
|
||||||
"SEARCH USING REFINED NAME?"));
|
"SEARCH USING REFINED NAME?"));
|
||||||
|
@ -918,7 +928,8 @@ bool GuiScraperSearch::saveMetadata(const ScraperSearchResult& result,
|
||||||
return metadataUpdated;
|
return metadataUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HelpPrompt> GuiScraperSearch::getHelpPrompts() {
|
std::vector<HelpPrompt> GuiScraperSearch::getHelpPrompts()
|
||||||
|
{
|
||||||
std::vector<HelpPrompt> prompts;
|
std::vector<HelpPrompt> prompts;
|
||||||
|
|
||||||
prompts.push_back(HelpPrompt("y", "refine search"));
|
prompts.push_back(HelpPrompt("y", "refine search"));
|
||||||
|
|
|
@ -64,19 +64,21 @@ public:
|
||||||
mAcceptCallback = acceptCallback;
|
mAcceptCallback = acceptCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSkipCallback(const std::function<void()> &skipCallback) {
|
void setSkipCallback(const std::function<void()>& skipCallback)
|
||||||
|
{
|
||||||
mSkipCallback = skipCallback;
|
mSkipCallback = skipCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCancelCallback(const std::function<void()> &cancelCallback) {
|
void setCancelCallback(const std::function<void()>& cancelCallback)
|
||||||
|
{
|
||||||
mCancelCallback = cancelCallback;
|
mCancelCallback = cancelCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input(InputConfig *config, Input input) override;
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
|
|
||||||
void render(const glm::mat4 &parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
|
||||||
std::vector<HelpPrompt> getHelpPrompts() override;
|
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
||||||
|
@ -84,7 +86,8 @@ public:
|
||||||
|
|
||||||
void onSizeChanged() override;
|
void onSizeChanged() override;
|
||||||
|
|
||||||
void decreaseScrapeCount() {
|
void decreaseScrapeCount()
|
||||||
|
{
|
||||||
if (mScrapeCount > 0)
|
if (mScrapeCount > 0)
|
||||||
mScrapeCount--;
|
mScrapeCount--;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +98,7 @@ public:
|
||||||
|
|
||||||
bool getFoundGame() { return mFoundGame; }
|
bool getFoundGame() { return mFoundGame; }
|
||||||
|
|
||||||
const std::string &getNameOverride() { return mLastSearch.nameOverride; }
|
const std::string& getNameOverride() { return mLastSearch.nameOverride; }
|
||||||
|
|
||||||
void onFocusGained() override { mGrid.onFocusGained(); }
|
void onFocusGained() override { mGrid.onFocusGained(); }
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,21 @@
|
||||||
#include "views/ViewController.h"
|
#include "views/ViewController.h"
|
||||||
#include "views/gamelist/IGameListView.h"
|
#include "views/gamelist/IGameListView.h"
|
||||||
|
|
||||||
GuiSettings::GuiSettings(Window *window, std::string title)
|
GuiSettings::GuiSettings(Window* window, std::string title)
|
||||||
: GuiComponent(window), mMenu(window, title), mGoToSystem(nullptr), mNeedsSaving(false),
|
: GuiComponent(window)
|
||||||
mNeedsReloadHelpPrompts(false), mNeedsCollectionsUpdate(false), mNeedsSorting(false),
|
, mMenu(window, title)
|
||||||
mNeedsSortingCollections(false), mNeedsResetFilters(false), mNeedsReloading(false), mNeedsGoToStart(false),
|
, mGoToSystem(nullptr)
|
||||||
mNeedsGoToSystem(false), mNeedsGoToGroupedCollections(false), mInvalidateCachedBackground(false)
|
, mNeedsSaving(false)
|
||||||
|
, mNeedsReloadHelpPrompts(false)
|
||||||
|
, mNeedsCollectionsUpdate(false)
|
||||||
|
, mNeedsSorting(false)
|
||||||
|
, mNeedsSortingCollections(false)
|
||||||
|
, mNeedsResetFilters(false)
|
||||||
|
, mNeedsReloading(false)
|
||||||
|
, mNeedsGoToStart(false)
|
||||||
|
, mNeedsGoToSystem(false)
|
||||||
|
, mNeedsGoToGroupedCollections(false)
|
||||||
|
, mInvalidateCachedBackground(false)
|
||||||
{
|
{
|
||||||
addChild(&mMenu);
|
addChild(&mMenu);
|
||||||
mMenu.addButton("BACK", "back", [this] { delete this; });
|
mMenu.addButton("BACK", "back", [this] { delete this; });
|
||||||
|
@ -174,10 +184,12 @@ void GuiSettings::addEditableTextComponent(const std::string label,
|
||||||
else if (isPassword && newVal == "") {
|
else if (isPassword && newVal == "") {
|
||||||
ed->setValue("");
|
ed->setValue("");
|
||||||
ed->setHiddenValue("");
|
ed->setHiddenValue("");
|
||||||
} else if (isPassword) {
|
}
|
||||||
|
else if (isPassword) {
|
||||||
ed->setValue("********");
|
ed->setValue("********");
|
||||||
ed->setHiddenValue(newVal);
|
ed->setHiddenValue(newVal);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ed->setValue(newVal);
|
ed->setValue(newVal);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -187,13 +199,14 @@ void GuiSettings::addEditableTextComponent(const std::string label,
|
||||||
// Never display the value if it's a password, instead set it to blank.
|
// Never display the value if it's a password, instead set it to blank.
|
||||||
if (isPassword)
|
if (isPassword)
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(
|
||||||
mWindow, getHelpStyle(), label, "", updateVal, false, "SAVE", "SAVE CHANGES?"));
|
mWindow, getHelpStyle(), label, "", updateVal, false, "SAVE", "SAVE CHANGES?"));
|
||||||
else
|
else
|
||||||
mWindow->pushGui(new GuiTextEditKeyboardPopup(mWindow, getHelpStyle(), label,
|
mWindow->pushGui(new GuiTextEditKeyboardPopup(mWindow, getHelpStyle(), label,
|
||||||
ed->getValue(), updateVal, false,
|
ed->getValue(), updateVal, false,
|
||||||
"SAVE", "SAVE CHANGES?"));
|
"SAVE", "SAVE CHANGES?"));
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
row.makeAcceptInputHandler([this, label, ed, updateVal, isPassword] {
|
row.makeAcceptInputHandler([this, label, ed, updateVal, isPassword] {
|
||||||
if (isPassword)
|
if (isPassword)
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), label, "", updateVal,
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), label, "", updateVal,
|
||||||
|
|
|
@ -147,7 +147,8 @@ void thegamesdb_generate_json_scraper_requests(
|
||||||
// using this regardless of whether the entry is an arcade game.
|
// using this regardless of whether the entry is an arcade game.
|
||||||
if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
|
if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
|
||||||
cleanName = Utils::String::removeParenthesis(params.game->metadata.get("name"));
|
cleanName = Utils::String::removeParenthesis(params.game->metadata.get("name"));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If not searching based on the metadata name, then check whether it's an
|
// If not searching based on the metadata name, then check whether it's an
|
||||||
// arcade game and if so expand to the full game name. This is required as
|
// arcade game and if so expand to the full game name. This is required as
|
||||||
// TheGamesDB has issues with searching using the short MAME names.
|
// TheGamesDB has issues with searching using the short MAME names.
|
||||||
|
@ -164,10 +165,10 @@ void thegamesdb_generate_json_scraper_requests(
|
||||||
return !std::isspace(static_cast<unsigned char>(c));
|
return !std::isspace(static_cast<unsigned char>(c));
|
||||||
}));
|
}));
|
||||||
cleanName.erase(
|
cleanName.erase(
|
||||||
std::find_if(cleanName.rbegin(), cleanName.rend(),
|
std::find_if(cleanName.rbegin(), cleanName.rend(),
|
||||||
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
[](char c) { return !std::isspace(static_cast<unsigned char>(c)); })
|
||||||
.base(),
|
.base(),
|
||||||
cleanName.end());
|
cleanName.end());
|
||||||
|
|
||||||
path += "/Games/ByGameName?" + apiKey +
|
path += "/Games/ByGameName?" + apiKey +
|
||||||
"&fields=players,publishers,genres,overview,last_updated,rating,"
|
"&fields=players,publishers,genres,overview,last_updated,rating,"
|
||||||
|
@ -456,7 +457,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
||||||
if (doc.HasMember("remaining_monthly_allowance") && doc.HasMember("extra_allowance")) {
|
if (doc.HasMember("remaining_monthly_allowance") && doc.HasMember("extra_allowance")) {
|
||||||
for (size_t i = 0; i < results.size(); i++) {
|
for (size_t i = 0; i < results.size(); i++) {
|
||||||
results[i].scraperRequestAllowance =
|
results[i].scraperRequestAllowance =
|
||||||
doc["remaining_monthly_allowance"].GetInt() + doc["extra_allowance"].GetInt();
|
doc["remaining_monthly_allowance"].GetInt() + doc["extra_allowance"].GetInt();
|
||||||
}
|
}
|
||||||
LOG(LogDebug) << "TheGamesDBJSONRequest::process(): "
|
LOG(LogDebug) << "TheGamesDBJSONRequest::process(): "
|
||||||
"Remaining monthly scraping allowance: "
|
"Remaining monthly scraping allowance: "
|
||||||
|
|
|
@ -17,12 +17,32 @@
|
||||||
#define FADE_IN_TIME 650
|
#define FADE_IN_TIME 650
|
||||||
|
|
||||||
DetailedGameListView::DetailedGameListView(Window* window, FileData* root)
|
DetailedGameListView::DetailedGameListView(Window* window, FileData* root)
|
||||||
: BasicGameListView(window, root), mThumbnail(window), mMarquee(window), mImage(window), mLblRating(window),
|
: BasicGameListView(window, root)
|
||||||
mLblReleaseDate(window), mLblDeveloper(window), mLblPublisher(window), mLblGenre(window), mLblPlayers(window),
|
, mThumbnail(window)
|
||||||
mLblLastPlayed(window), mLblPlayCount(window), mBadges(window), mRating(window), mReleaseDate(window),
|
, mMarquee(window)
|
||||||
mDeveloper(window),
|
, mImage(window)
|
||||||
mPublisher(window), mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window), mName(window),
|
, mLblRating(window)
|
||||||
mDescContainer(window), mDescription(window), mGamelistInfo(window), mLastUpdated(nullptr)
|
, mLblReleaseDate(window)
|
||||||
|
, mLblDeveloper(window)
|
||||||
|
, mLblPublisher(window)
|
||||||
|
, mLblGenre(window)
|
||||||
|
, mLblPlayers(window)
|
||||||
|
, mLblLastPlayed(window)
|
||||||
|
, mLblPlayCount(window)
|
||||||
|
, mBadges(window)
|
||||||
|
, mRating(window)
|
||||||
|
, mReleaseDate(window)
|
||||||
|
, mDeveloper(window)
|
||||||
|
, mPublisher(window)
|
||||||
|
, mGenre(window)
|
||||||
|
, mPlayers(window)
|
||||||
|
, mLastPlayed(window)
|
||||||
|
, mPlayCount(window)
|
||||||
|
, mName(window)
|
||||||
|
, mDescContainer(window)
|
||||||
|
, mDescription(window)
|
||||||
|
, mGamelistInfo(window)
|
||||||
|
, mLastUpdated(nullptr)
|
||||||
{
|
{
|
||||||
const float padding = 0.01f;
|
const float padding = 0.01f;
|
||||||
|
|
||||||
|
@ -111,7 +131,8 @@ DetailedGameListView::DetailedGameListView(Window* window, FileData* root)
|
||||||
initMDValues();
|
initMDValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetailedGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme) {
|
void DetailedGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
||||||
|
{
|
||||||
BasicGameListView::onThemeChanged(theme);
|
BasicGameListView::onThemeChanged(theme);
|
||||||
|
|
||||||
using namespace ThemeFlags;
|
using namespace ThemeFlags;
|
||||||
|
@ -124,21 +145,21 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& them
|
||||||
mName.applyTheme(theme, getName(), "md_name", ALL);
|
mName.applyTheme(theme, getName(), "md_name", ALL);
|
||||||
|
|
||||||
initMDLabels();
|
initMDLabels();
|
||||||
std::vector<TextComponent *> labels = getMDLabels();
|
std::vector<TextComponent*> labels = getMDLabels();
|
||||||
assert(labels.size() == 8);
|
assert(labels.size() == 8);
|
||||||
std::vector<std::string> lblElements = {
|
std::vector<std::string> lblElements = {
|
||||||
"md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher",
|
"md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher",
|
||||||
"md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount"};
|
"md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount"};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < labels.size(); i++)
|
for (unsigned int i = 0; i < labels.size(); i++)
|
||||||
labels[i]->applyTheme(theme, getName(), lblElements[i], ALL);
|
labels[i]->applyTheme(theme, getName(), lblElements[i], ALL);
|
||||||
|
|
||||||
initMDValues();
|
initMDValues();
|
||||||
std::vector<GuiComponent *> values = getMDValues();
|
std::vector<GuiComponent*> values = getMDValues();
|
||||||
assert(values.size() == 9);
|
assert(values.size() == 9);
|
||||||
std::vector<std::string> valElements = {"md_rating", "md_releasedate", "md_developer",
|
std::vector<std::string> valElements = {"md_rating", "md_releasedate", "md_developer",
|
||||||
"md_publisher", "md_genre", "md_players",
|
"md_publisher", "md_genre", "md_players",
|
||||||
"md_badges", "md_lastplayed", "md_playcount"};
|
"md_badges", "md_lastplayed", "md_playcount"};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < values.size(); i++)
|
for (unsigned int i = 0; i < values.size(); i++)
|
||||||
values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT);
|
values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT);
|
||||||
|
@ -402,7 +423,8 @@ void DetailedGameListView::updateInfoPanel()
|
||||||
mLastPlayed.setValue(file->metadata.get("lastplayed"));
|
mLastPlayed.setValue(file->metadata.get("lastplayed"));
|
||||||
mPlayCount.setValue(file->metadata.get("playcount"));
|
mPlayCount.setValue(file->metadata.get("playcount"));
|
||||||
}
|
}
|
||||||
} else if (file->getType() == FOLDER) {
|
}
|
||||||
|
else if (file->getType() == FOLDER) {
|
||||||
if (!hideMetaDataFields) {
|
if (!hideMetaDataFields) {
|
||||||
mLastPlayed.setValue(file->metadata.get("lastplayed"));
|
mLastPlayed.setValue(file->metadata.get("lastplayed"));
|
||||||
mLblPlayCount.setVisible(false);
|
mLblPlayCount.setVisible(false);
|
||||||
|
|
|
@ -20,12 +20,31 @@
|
||||||
#define FADE_IN_TIME 650
|
#define FADE_IN_TIME 650
|
||||||
|
|
||||||
GridGameListView::GridGameListView(Window* window, FileData* root)
|
GridGameListView::GridGameListView(Window* window, FileData* root)
|
||||||
: ISimpleGameListView(window, root), mGrid(window), mMarquee(window), mImage(window), mLblRating(window),
|
: ISimpleGameListView(window, root)
|
||||||
mLblReleaseDate(window), mLblDeveloper(window), mLblPublisher(window), mLblGenre(window), mLblPlayers(window),
|
, mGrid(window)
|
||||||
mLblLastPlayed(window), mLblPlayCount(window), mBadges(window), mRating(window), mReleaseDate(window),
|
, mMarquee(window)
|
||||||
mDeveloper(window),
|
, mImage(window)
|
||||||
mPublisher(window), mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window), mName(window),
|
, mLblRating(window)
|
||||||
mDescContainer(window), mDescription(window), mGamelistInfo(window)
|
, mLblReleaseDate(window)
|
||||||
|
, mLblDeveloper(window)
|
||||||
|
, mLblPublisher(window)
|
||||||
|
, mLblGenre(window)
|
||||||
|
, mLblPlayers(window)
|
||||||
|
, mLblLastPlayed(window)
|
||||||
|
, mLblPlayCount(window)
|
||||||
|
, mBadges(window)
|
||||||
|
, mRating(window)
|
||||||
|
, mReleaseDate(window)
|
||||||
|
, mDeveloper(window)
|
||||||
|
, mPublisher(window)
|
||||||
|
, mGenre(window)
|
||||||
|
, mPlayers(window)
|
||||||
|
, mLastPlayed(window)
|
||||||
|
, mPlayCount(window)
|
||||||
|
, mName(window)
|
||||||
|
, mDescContainer(window)
|
||||||
|
, mDescription(window)
|
||||||
|
, mGamelistInfo(window)
|
||||||
{
|
{
|
||||||
const float padding = 0.01f;
|
const float padding = 0.01f;
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,12 @@ protected:
|
||||||
|
|
||||||
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'.
|
||||||
FileData *firstGameEntry;
|
FileData* firstGameEntry;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateInfoPanel();
|
void updateInfoPanel();
|
||||||
|
|
||||||
const std::string getImagePath(FileData *file);
|
const std::string getImagePath(FileData* file);
|
||||||
|
|
||||||
void initMDLabels();
|
void initMDLabels();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class VideoComponent;
|
||||||
class VideoGameListView : public BasicGameListView
|
class VideoGameListView : public BasicGameListView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VideoGameListView(Window *window, FileData *root);
|
VideoGameListView(Window* window, FileData* root);
|
||||||
|
|
||||||
virtual ~VideoGameListView() noexcept;
|
virtual ~VideoGameListView() noexcept;
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,22 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
GuiComponent::GuiComponent(Window *window)
|
GuiComponent::GuiComponent(Window* window)
|
||||||
: mWindow(window), mParent(nullptr), mOpacity(255), mColor(0), mSaturation(1.0f), mColorShift(0),
|
: mWindow(window)
|
||||||
mColorShiftEnd(0),
|
, mParent(nullptr)
|
||||||
mPosition({}), mOrigin({}), mRotationOrigin(0.5f, 0.5f), mSize({}), mIsProcessing(false), mVisible(true),
|
, mOpacity(255)
|
||||||
mEnabled(true), mTransform(Renderer::getIdentity())
|
, mColor(0)
|
||||||
|
, mSaturation(1.0f)
|
||||||
|
, mColorShift(0)
|
||||||
|
, mColorShiftEnd(0)
|
||||||
|
, mPosition({})
|
||||||
|
, mOrigin({})
|
||||||
|
, mRotationOrigin(0.5f, 0.5f)
|
||||||
|
, mSize({})
|
||||||
|
, mIsProcessing(false)
|
||||||
|
, mVisible(true)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mTransform(Renderer::getIdentity())
|
||||||
{
|
{
|
||||||
for (unsigned char i = 0; i < MAX_ANIMATIONS; i++)
|
for (unsigned char i = 0; i < MAX_ANIMATIONS; i++)
|
||||||
mAnimationMap[i] = nullptr;
|
mAnimationMap[i] = nullptr;
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Window;
|
||||||
class GuiComponent
|
class GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiComponent(Window *window);
|
GuiComponent(Window* window);
|
||||||
|
|
||||||
virtual ~GuiComponent() noexcept;
|
virtual ~GuiComponent() noexcept;
|
||||||
|
|
||||||
|
@ -231,15 +231,15 @@ public:
|
||||||
const static unsigned char MAX_ANIMATIONS = 4;
|
const static unsigned char MAX_ANIMATIONS = 4;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderChildren(const glm::mat4 &transform) const;
|
void renderChildren(const glm::mat4& transform) const;
|
||||||
|
|
||||||
void updateSelf(int deltaTime); // Updates animations.
|
void updateSelf(int deltaTime); // Updates animations.
|
||||||
void updateChildren(int deltaTime); // Updates animations.
|
void updateChildren(int deltaTime); // Updates animations.
|
||||||
|
|
||||||
Window *mWindow;
|
Window* mWindow;
|
||||||
|
|
||||||
GuiComponent *mParent;
|
GuiComponent* mParent;
|
||||||
std::vector<GuiComponent *> mChildren;
|
std::vector<GuiComponent*> mChildren;
|
||||||
|
|
||||||
unsigned char mOpacity;
|
unsigned char mOpacity;
|
||||||
unsigned int mColor;
|
unsigned int mColor;
|
||||||
|
|
|
@ -80,7 +80,7 @@ private:
|
||||||
static CURLM* s_multi_handle;
|
static CURLM* s_multi_handle;
|
||||||
|
|
||||||
Status mStatus;
|
Status mStatus;
|
||||||
CURL *mHandle;
|
CURL* mHandle;
|
||||||
|
|
||||||
std::stringstream mContent;
|
std::stringstream mContent;
|
||||||
std::string mErrorMsg;
|
std::string mErrorMsg;
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
#include "resources/TextureResource.h"
|
#include "resources/TextureResource.h"
|
||||||
|
|
||||||
// Available slot definitions.
|
// Available slot definitions.
|
||||||
std::vector<std::string> BadgesComponent::mSlots = {SLOT_FAVORITE, SLOT_COMPLETED, SLOT_KIDS, SLOT_BROKEN,
|
std::vector<std::string> BadgesComponent::mSlots = {SLOT_FAVORITE, SLOT_COMPLETED, SLOT_KIDS,
|
||||||
SLOT_ALTERNATIVE_EMULATOR};
|
SLOT_BROKEN, SLOT_ALTERNATIVE_EMULATOR};
|
||||||
|
|
||||||
BadgesComponent::BadgesComponent(Window *window)
|
BadgesComponent::BadgesComponent(Window* window)
|
||||||
: FlexboxComponent(window) {
|
: FlexboxComponent(window)
|
||||||
|
{
|
||||||
|
|
||||||
mBadgeIcons = std::map<std::string, std::string>();
|
mBadgeIcons = std::map<std::string, std::string>();
|
||||||
mBadgeIcons[SLOT_FAVORITE] = ":/graphics/badge_favorite.svg";
|
mBadgeIcons[SLOT_FAVORITE] = ":/graphics/badge_favorite.svg";
|
||||||
|
@ -45,16 +46,17 @@ BadgesComponent::BadgesComponent(Window *window)
|
||||||
mImageComponents.insert({SLOT_ALTERNATIVE_EMULATOR, mImageAltEmu});
|
mImageComponents.insert({SLOT_ALTERNATIVE_EMULATOR, mImageAltEmu});
|
||||||
}
|
}
|
||||||
|
|
||||||
BadgesComponent::~BadgesComponent() noexcept {
|
BadgesComponent::~BadgesComponent() noexcept
|
||||||
for (GuiComponent *c: mChildren)
|
{
|
||||||
|
for (GuiComponent* c : mChildren)
|
||||||
c->clearChildren();
|
c->clearChildren();
|
||||||
clearChildren();
|
clearChildren();
|
||||||
mBadgeIcons.clear();
|
mBadgeIcons.clear();
|
||||||
mImageComponents.clear();
|
mImageComponents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BadgesComponent::setValue(const std::string& value)
|
||||||
void BadgesComponent::setValue(const std::string &value) {
|
{
|
||||||
mChildren.clear();
|
mChildren.clear();
|
||||||
if (!value.empty()) {
|
if (!value.empty()) {
|
||||||
std::string temp;
|
std::string temp;
|
||||||
|
@ -94,7 +96,8 @@ void BadgesComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
|
|
||||||
bool imgChanged = false;
|
bool imgChanged = false;
|
||||||
for (auto& slot : mSlots) {
|
for (auto& slot : mSlots) {
|
||||||
if (properties & PATH && elem->has(slot) && mBadgeIcons[slot] != elem->get<std::string>(slot)) {
|
if (properties & PATH && elem->has(slot) &&
|
||||||
|
mBadgeIcons[slot] != elem->get<std::string>(slot)) {
|
||||||
mBadgeIcons[slot] = elem->get<std::string>(slot);
|
mBadgeIcons[slot] = elem->get<std::string>(slot);
|
||||||
mImageComponents.find(slot)->second.setImage(mBadgeIcons[slot], false, true, true);
|
mImageComponents.find(slot)->second.setImage(mBadgeIcons[slot], false, true, true);
|
||||||
imgChanged = true;
|
imgChanged = true;
|
||||||
|
|
|
@ -27,16 +27,16 @@ class TextureResource;
|
||||||
class BadgesComponent : public FlexboxComponent
|
class BadgesComponent : public FlexboxComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BadgesComponent(Window *window);
|
BadgesComponent(Window* window);
|
||||||
~BadgesComponent() noexcept;
|
~BadgesComponent() noexcept;
|
||||||
|
|
||||||
std::string getValue() const override;
|
std::string getValue() const override;
|
||||||
// Should be a list of strings.
|
// Should be a list of strings.
|
||||||
void setValue(const std::string &value) override;
|
void setValue(const std::string& value) override;
|
||||||
|
|
||||||
virtual void applyTheme(const std::shared_ptr<ThemeData> &theme,
|
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
const std::string &view,
|
const std::string& view,
|
||||||
const std::string &element,
|
const std::string& element,
|
||||||
unsigned int properties) override;
|
unsigned int properties) override;
|
||||||
|
|
||||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
|
@ -12,15 +12,24 @@
|
||||||
#include "resources/Font.h"
|
#include "resources/Font.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
|
||||||
ButtonComponent::ButtonComponent(Window *window,
|
ButtonComponent::ButtonComponent(Window* window,
|
||||||
const std::string &text,
|
const std::string& text,
|
||||||
const std::string &helpText,
|
const std::string& helpText,
|
||||||
const std::function<void()> &func,
|
const std::function<void()>& func,
|
||||||
bool upperCase,
|
bool upperCase,
|
||||||
bool flatStyle)
|
bool flatStyle)
|
||||||
: GuiComponent{window}, mBox{window, ":/graphics/button.svg"}, mFont{Font::get(FONT_SIZE_MEDIUM)}, mPadding{{}},
|
: GuiComponent{window}
|
||||||
mFocused{false}, mEnabled{true}, mFlatStyle{flatStyle}, mTextColorFocused{0xFFFFFFFF},
|
, mBox{window, ":/graphics/button.svg"}
|
||||||
mTextColorUnfocused{0x777777FF}, mFlatColorFocused{0x878787FF}, mFlatColorUnfocused{0x60606025} {
|
, mFont{Font::get(FONT_SIZE_MEDIUM)}
|
||||||
|
, mPadding{{}}
|
||||||
|
, mFocused{false}
|
||||||
|
, mEnabled{true}
|
||||||
|
, mFlatStyle{flatStyle}
|
||||||
|
, mTextColorFocused{0xFFFFFFFF}
|
||||||
|
, mTextColorUnfocused{0x777777FF}
|
||||||
|
, mFlatColorFocused{0x878787FF}
|
||||||
|
, mFlatColorUnfocused{0x60606025}
|
||||||
|
{
|
||||||
setPressedFunc(func);
|
setPressedFunc(func);
|
||||||
setText(text, helpText, upperCase);
|
setText(text, helpText, upperCase);
|
||||||
|
|
||||||
|
@ -28,7 +37,8 @@ ButtonComponent::ButtonComponent(Window *window,
|
||||||
updateImage();
|
updateImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::onSizeChanged() {
|
void ButtonComponent::onSizeChanged()
|
||||||
|
{
|
||||||
if (mFlatStyle)
|
if (mFlatStyle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -39,24 +49,27 @@ void ButtonComponent::onSizeChanged() {
|
||||||
glm::vec2{-cornerSize.x * 2.0f, -cornerSize.y * 2.0f});
|
glm::vec2{-cornerSize.x * 2.0f, -cornerSize.y * 2.0f});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::onFocusGained() {
|
void ButtonComponent::onFocusGained()
|
||||||
|
{
|
||||||
mFocused = true;
|
mFocused = true;
|
||||||
if (!mFlatStyle)
|
if (!mFlatStyle)
|
||||||
updateImage();
|
updateImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::onFocusLost() {
|
void ButtonComponent::onFocusLost()
|
||||||
|
{
|
||||||
mFocused = false;
|
mFocused = false;
|
||||||
if (!mFlatStyle)
|
if (!mFlatStyle)
|
||||||
updateImage();
|
updateImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::setText(const std::string &text, const std::string &helpText, bool upperCase) {
|
void ButtonComponent::setText(const std::string& text, const std::string& helpText, bool upperCase)
|
||||||
|
{
|
||||||
mText = upperCase ? Utils::String::toUpper(text) : text;
|
mText = upperCase ? Utils::String::toUpper(text) : text;
|
||||||
mHelpText = helpText;
|
mHelpText = helpText;
|
||||||
|
|
||||||
mTextCache =
|
mTextCache =
|
||||||
std::unique_ptr<TextCache>(mFont->buildTextCache(mText, 0.0f, 0.0f, getCurTextColor()));
|
std::unique_ptr<TextCache>(mFont->buildTextCache(mText, 0.0f, 0.0f, getCurTextColor()));
|
||||||
|
|
||||||
float minWidth = mFont->sizeText("DELETE").x + (12.0f * Renderer::getScreenWidthModifier());
|
float minWidth = mFont->sizeText("DELETE").x + (12.0f * Renderer::getScreenWidthModifier());
|
||||||
setSize(std::max(mTextCache->metrics.size.x + (12.0f * Renderer::getScreenWidthModifier()),
|
setSize(std::max(mTextCache->metrics.size.x + (12.0f * Renderer::getScreenWidthModifier()),
|
||||||
|
@ -66,13 +79,15 @@ void ButtonComponent::setText(const std::string &text, const std::string &helpTe
|
||||||
updateHelpPrompts();
|
updateHelpPrompts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::setEnabled(bool state) {
|
void ButtonComponent::setEnabled(bool state)
|
||||||
|
{
|
||||||
mEnabled = state;
|
mEnabled = state;
|
||||||
if (!mFlatStyle)
|
if (!mFlatStyle)
|
||||||
updateImage();
|
updateImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::setPadding(const glm::vec4 padding) {
|
void ButtonComponent::setPadding(const glm::vec4 padding)
|
||||||
|
{
|
||||||
if (mPadding == padding)
|
if (mPadding == padding)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -80,7 +95,8 @@ void ButtonComponent::setPadding(const glm::vec4 padding) {
|
||||||
onSizeChanged();
|
onSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ButtonComponent::input(InputConfig *config, Input input) {
|
bool ButtonComponent::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
if (config->isMappedTo("a", input) && input.value != 0) {
|
if (config->isMappedTo("a", input) && input.value != 0) {
|
||||||
if (mPressedFunc && mEnabled)
|
if (mPressedFunc && mEnabled)
|
||||||
mPressedFunc();
|
mPressedFunc();
|
||||||
|
@ -90,7 +106,8 @@ bool ButtonComponent::input(InputConfig *config, Input input) {
|
||||||
return GuiComponent::input(config, input);
|
return GuiComponent::input(config, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::render(const glm::mat4 &parentTrans) {
|
void ButtonComponent::render(const glm::mat4& parentTrans)
|
||||||
|
{
|
||||||
glm::mat4 trans{parentTrans * getTransform()};
|
glm::mat4 trans{parentTrans * getTransform()};
|
||||||
|
|
||||||
if (mFlatStyle) {
|
if (mFlatStyle) {
|
||||||
|
@ -99,13 +116,15 @@ void ButtonComponent::render(const glm::mat4 &parentTrans) {
|
||||||
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||||
mSize.y - mPadding.y - mPadding.w, mFlatColorFocused,
|
mSize.y - mPadding.y - mPadding.w, mFlatColorFocused,
|
||||||
mFlatColorFocused);
|
mFlatColorFocused);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Renderer::setMatrix(trans);
|
Renderer::setMatrix(trans);
|
||||||
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||||
mSize.y - mPadding.y - mPadding.w, mFlatColorUnfocused,
|
mSize.y - mPadding.y - mPadding.w, mFlatColorUnfocused,
|
||||||
mFlatColorUnfocused);
|
mFlatColorUnfocused);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mBox.render(trans);
|
mBox.render(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,20 +150,23 @@ void ButtonComponent::render(const glm::mat4 &parentTrans) {
|
||||||
renderChildren(trans);
|
renderChildren(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HelpPrompt> ButtonComponent::getHelpPrompts() {
|
std::vector<HelpPrompt> ButtonComponent::getHelpPrompts()
|
||||||
|
{
|
||||||
std::vector<HelpPrompt> prompts;
|
std::vector<HelpPrompt> prompts;
|
||||||
prompts.push_back(HelpPrompt("a", mHelpText.empty() ? mText.c_str() : mHelpText.c_str()));
|
prompts.push_back(HelpPrompt("a", mHelpText.empty() ? mText.c_str() : mHelpText.c_str()));
|
||||||
return prompts;
|
return prompts;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ButtonComponent::getCurTextColor() const {
|
unsigned int ButtonComponent::getCurTextColor() const
|
||||||
|
{
|
||||||
if (!mFocused)
|
if (!mFocused)
|
||||||
return mTextColorUnfocused;
|
return mTextColorUnfocused;
|
||||||
else
|
else
|
||||||
return mTextColorFocused;
|
return mTextColorFocused;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonComponent::updateImage() {
|
void ButtonComponent::updateImage()
|
||||||
|
{
|
||||||
if (!mEnabled || !mPressedFunc) {
|
if (!mEnabled || !mPressedFunc) {
|
||||||
mBox.setImagePath(":/graphics/button_filled.svg");
|
mBox.setImagePath(":/graphics/button_filled.svg");
|
||||||
mBox.setCenterColor(0x770000FF);
|
mBox.setCenterColor(0x770000FF);
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
|
|
||||||
class TextCache;
|
class TextCache;
|
||||||
|
|
||||||
class ButtonComponent : public GuiComponent {
|
class ButtonComponent : public GuiComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
ButtonComponent(Window *window,
|
ButtonComponent(Window* window,
|
||||||
const std::string &text = "",
|
const std::string& text = "",
|
||||||
const std::string &helpText = "",
|
const std::string& helpText = "",
|
||||||
const std::function<void()> &func = nullptr,
|
const std::function<void()>& func = nullptr,
|
||||||
bool upperCase = true,
|
bool upperCase = true,
|
||||||
bool flatStyle = false);
|
bool flatStyle = false);
|
||||||
|
|
||||||
|
@ -29,9 +30,9 @@ public:
|
||||||
|
|
||||||
void onFocusLost() override;
|
void onFocusLost() override;
|
||||||
|
|
||||||
void setText(const std::string &text, const std::string &helpText, bool upperCase = true);
|
void setText(const std::string& text, const std::string& helpText, bool upperCase = true);
|
||||||
|
|
||||||
const std::string &getText() const { return mText; }
|
const std::string& getText() const { return mText; }
|
||||||
|
|
||||||
void setPressedFunc(std::function<void()> f) { mPressedFunc = f; }
|
void setPressedFunc(std::function<void()> f) { mPressedFunc = f; }
|
||||||
|
|
||||||
|
@ -45,11 +46,11 @@ public:
|
||||||
|
|
||||||
void setFlatColorUnfocused(unsigned int color) { mFlatColorUnfocused = color; }
|
void setFlatColorUnfocused(unsigned int color) { mFlatColorUnfocused = color; }
|
||||||
|
|
||||||
const std::function<void()> &getPressedFunc() const { return mPressedFunc; }
|
const std::function<void()>& getPressedFunc() const { return mPressedFunc; }
|
||||||
|
|
||||||
bool input(InputConfig *config, Input input) override;
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
void render(const glm::mat4 &parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
|
||||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ const ComponentGrid::GridEntry* ComponentGrid::getCellAt(int x, int y) const
|
||||||
|
|
||||||
bool ComponentGrid::input(InputConfig* config, Input input)
|
bool ComponentGrid::input(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
const GridEntry *cursorEntry = getCellAt(mCursor);
|
const GridEntry* cursorEntry = getCellAt(mCursor);
|
||||||
if (cursorEntry && cursorEntry->component->input(config, input))
|
if (cursorEntry && cursorEntry->component->input(config, input))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -287,11 +287,12 @@ void ComponentGrid::resetCursor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComponentGrid::moveCursor(glm::ivec2 dir) {
|
bool ComponentGrid::moveCursor(glm::ivec2 dir)
|
||||||
|
{
|
||||||
assert(dir.x || dir.y);
|
assert(dir.x || dir.y);
|
||||||
|
|
||||||
const glm::ivec2 origCursor{mCursor};
|
const glm::ivec2 origCursor{mCursor};
|
||||||
const GridEntry *currentCursorEntry = getCellAt(mCursor);
|
const GridEntry* currentCursorEntry = getCellAt(mCursor);
|
||||||
glm::ivec2 searchAxis(dir.x == 0, dir.y == 0);
|
glm::ivec2 searchAxis(dir.x == 0, dir.y == 0);
|
||||||
|
|
||||||
// Logic to handle entries that span several cells.
|
// Logic to handle entries that span several cells.
|
||||||
|
@ -325,7 +326,7 @@ bool ComponentGrid::moveCursor(glm::ivec2 dir) {
|
||||||
while (mCursor.x >= 0 && mCursor.y >= 0 && mCursor.x < mGridSize.x && mCursor.y < mGridSize.y) {
|
while (mCursor.x >= 0 && mCursor.y >= 0 && mCursor.x < mGridSize.x && mCursor.y < mGridSize.y) {
|
||||||
mCursor = mCursor + dir;
|
mCursor = mCursor + dir;
|
||||||
glm::ivec2 curDirPos{mCursor};
|
glm::ivec2 curDirPos{mCursor};
|
||||||
const GridEntry *cursorEntry;
|
const GridEntry* cursorEntry;
|
||||||
|
|
||||||
// Spread out on search axis+
|
// Spread out on search axis+
|
||||||
while (mCursor.x < mGridSize.x && mCursor.y < mGridSize.y && mCursor.x >= 0 &&
|
while (mCursor.x < mGridSize.x && mCursor.y < mGridSize.y && mCursor.x >= 0 &&
|
||||||
|
@ -367,7 +368,8 @@ bool ComponentGrid::moveCursor(glm::ivec2 dir) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComponentGrid::moveCursorTo(int xPos, int yPos, bool selectLeftCell) {
|
void ComponentGrid::moveCursorTo(int xPos, int yPos, bool selectLeftCell)
|
||||||
|
{
|
||||||
const glm::ivec2 origCursor{mCursor};
|
const glm::ivec2 origCursor{mCursor};
|
||||||
|
|
||||||
if (xPos != -1)
|
if (xPos != -1)
|
||||||
|
@ -375,7 +377,7 @@ void ComponentGrid::moveCursorTo(int xPos, int yPos, bool selectLeftCell) {
|
||||||
if (yPos != -1)
|
if (yPos != -1)
|
||||||
mCursor.y = yPos;
|
mCursor.y = yPos;
|
||||||
|
|
||||||
const GridEntry *currentCursorEntry = getCellAt(mCursor);
|
const GridEntry* currentCursorEntry = getCellAt(mCursor);
|
||||||
|
|
||||||
// If requested, select the leftmost cell of entries wider than 1 cell.
|
// If requested, select the leftmost cell of entries wider than 1 cell.
|
||||||
if (selectLeftCell && mCursor.x > currentCursorEntry->pos.x)
|
if (selectLeftCell && mCursor.x > currentCursorEntry->pos.x)
|
||||||
|
@ -384,14 +386,16 @@ void ComponentGrid::moveCursorTo(int xPos, int yPos, bool selectLeftCell) {
|
||||||
onCursorMoved(origCursor, mCursor);
|
onCursorMoved(origCursor, mCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComponentGrid::onFocusLost() {
|
void ComponentGrid::onFocusLost()
|
||||||
const GridEntry *cursorEntry = getCellAt(mCursor);
|
{
|
||||||
|
const GridEntry* cursorEntry = getCellAt(mCursor);
|
||||||
if (cursorEntry)
|
if (cursorEntry)
|
||||||
cursorEntry->component->onFocusLost();
|
cursorEntry->component->onFocusLost();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComponentGrid::onFocusGained() {
|
void ComponentGrid::onFocusGained()
|
||||||
const GridEntry *cursorEntry = getCellAt(mCursor);
|
{
|
||||||
|
const GridEntry* cursorEntry = getCellAt(mCursor);
|
||||||
if (cursorEntry)
|
if (cursorEntry)
|
||||||
cursorEntry->component->onFocusGained();
|
cursorEntry->component->onFocusGained();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,33 +30,35 @@ namespace GridFlags
|
||||||
} // namespace GridFlags
|
} // namespace GridFlags
|
||||||
|
|
||||||
// Provides basic layout of components in an X*Y grid.
|
// Provides basic layout of components in an X*Y grid.
|
||||||
class ComponentGrid : public GuiComponent {
|
class ComponentGrid : public GuiComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
ComponentGrid(Window *window, const glm::ivec2 &gridDimensions);
|
ComponentGrid(Window* window, const glm::ivec2& gridDimensions);
|
||||||
|
|
||||||
virtual ~ComponentGrid();
|
virtual ~ComponentGrid();
|
||||||
|
|
||||||
bool removeEntry(const std::shared_ptr<GuiComponent> &comp);
|
bool removeEntry(const std::shared_ptr<GuiComponent>& comp);
|
||||||
|
|
||||||
void setEntry(const std::shared_ptr<GuiComponent> &comp,
|
void setEntry(const std::shared_ptr<GuiComponent>& comp,
|
||||||
const glm::ivec2 &pos,
|
const glm::ivec2& pos,
|
||||||
bool canFocus,
|
bool canFocus,
|
||||||
bool resize = true,
|
bool resize = true,
|
||||||
const glm::ivec2 &size = glm::ivec2{1, 1},
|
const glm::ivec2& size = glm::ivec2{1, 1},
|
||||||
unsigned int border = GridFlags::BORDER_NONE,
|
unsigned int border = GridFlags::BORDER_NONE,
|
||||||
GridFlags::UpdateType updateType = GridFlags::UPDATE_ALWAYS);
|
GridFlags::UpdateType updateType = GridFlags::UPDATE_ALWAYS);
|
||||||
|
|
||||||
void setPastBoundaryCallback(const std::function<bool(InputConfig *config, Input input)> &func) {
|
void setPastBoundaryCallback(const std::function<bool(InputConfig* config, Input input)>& func)
|
||||||
|
{
|
||||||
mPastBoundaryCallback = func;
|
mPastBoundaryCallback = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
void textInput(const std::string &text) override;
|
void textInput(const std::string& text) override;
|
||||||
|
|
||||||
bool input(InputConfig *config, Input input) override;
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
|
|
||||||
void render(const glm::mat4 &parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
|
||||||
void onSizeChanged() override;
|
void onSizeChanged() override;
|
||||||
|
|
||||||
|
@ -80,10 +82,11 @@ public:
|
||||||
// Pass -1 for xPos or yPos to keep its axis cursor position.
|
// Pass -1 for xPos or yPos to keep its axis cursor position.
|
||||||
void moveCursorTo(int xPos, int yPos, bool selectLeftCell = false);
|
void moveCursorTo(int xPos, int yPos, bool selectLeftCell = false);
|
||||||
|
|
||||||
void setCursorTo(const std::shared_ptr<GuiComponent> &comp);
|
void setCursorTo(const std::shared_ptr<GuiComponent>& comp);
|
||||||
|
|
||||||
std::shared_ptr<GuiComponent> getSelectedComponent() {
|
std::shared_ptr<GuiComponent> getSelectedComponent()
|
||||||
const GridEntry *e = getCellAt(mCursor);
|
{
|
||||||
|
const GridEntry* e = getCellAt(mCursor);
|
||||||
if (e)
|
if (e)
|
||||||
return e->component;
|
return e->component;
|
||||||
else
|
else
|
||||||
|
@ -129,25 +132,25 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update position and size.
|
// Update position and size.
|
||||||
void updateCellComponent(const GridEntry &cell);
|
void updateCellComponent(const GridEntry& cell);
|
||||||
|
|
||||||
void updateSeparators();
|
void updateSeparators();
|
||||||
|
|
||||||
void onCursorMoved(glm::ivec2 from, glm::ivec2 to);
|
void onCursorMoved(glm::ivec2 from, glm::ivec2 to);
|
||||||
|
|
||||||
const GridEntry *getCellAt(int x, int y) const;
|
const GridEntry* getCellAt(int x, int y) const;
|
||||||
|
|
||||||
const GridEntry *getCellAt(const glm::ivec2 &pos) const { return getCellAt(pos.x, pos.y); }
|
const GridEntry* getCellAt(const glm::ivec2& pos) const { return getCellAt(pos.x, pos.y); }
|
||||||
|
|
||||||
std::vector<std::vector<float>> mSeparators;
|
std::vector<std::vector<float>> mSeparators;
|
||||||
glm::ivec2 mGridSize;
|
glm::ivec2 mGridSize;
|
||||||
std::vector<GridEntry> mCells;
|
std::vector<GridEntry> mCells;
|
||||||
glm::ivec2 mCursor;
|
glm::ivec2 mCursor;
|
||||||
|
|
||||||
std::function<bool(InputConfig *config, Input input)> mPastBoundaryCallback;
|
std::function<bool(InputConfig* config, Input input)> mPastBoundaryCallback;
|
||||||
|
|
||||||
float *mRowHeights;
|
float* mRowHeights;
|
||||||
float *mColWidths;
|
float* mColWidths;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_CORE_COMPONENTS_COMPONENT_GRID_H
|
#endif // ES_CORE_COMPONENTS_COMPONENT_GRID_H
|
||||||
|
|
|
@ -71,10 +71,11 @@ bool ComponentList::input(InputConfig* config, Input input)
|
||||||
if (mEntries.at(mCursor).data.input_handler) {
|
if (mEntries.at(mCursor).data.input_handler) {
|
||||||
if (mEntries.at(mCursor).data.input_handler(config, input))
|
if (mEntries.at(mCursor).data.input_handler(config, input))
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// No input handler assigned, do the default, which is to give it
|
// No input handler assigned, do the default, which is to give it
|
||||||
// to the rightmost element in the row.
|
// to the rightmost element in the row.
|
||||||
auto &row = mEntries.at(mCursor).data;
|
auto& row = mEntries.at(mCursor).data;
|
||||||
if (row.elements.size()) {
|
if (row.elements.size()) {
|
||||||
if (row.elements.back().component->input(config, input))
|
if (row.elements.back().component->input(config, input))
|
||||||
return true;
|
return true;
|
||||||
|
@ -196,7 +197,7 @@ void ComponentList::render(const glm::mat4& parentTrans)
|
||||||
std::vector<GuiComponent*> drawAfterCursor;
|
std::vector<GuiComponent*> drawAfterCursor;
|
||||||
bool drawAll;
|
bool drawAll;
|
||||||
for (size_t i = 0; i < mEntries.size(); i++) {
|
for (size_t i = 0; i < mEntries.size(); i++) {
|
||||||
auto &entry = mEntries.at(i);
|
auto& entry = mEntries.at(i);
|
||||||
drawAll = !mFocused || i != static_cast<unsigned int>(mCursor);
|
drawAll = !mFocused || i != static_cast<unsigned int>(mCursor);
|
||||||
for (auto it = entry.data.elements.cbegin(); it != entry.data.elements.cend(); it++) {
|
for (auto it = entry.data.elements.cbegin(); it != entry.data.elements.cend(); it++) {
|
||||||
if (drawAll || it->invert_when_selected) {
|
if (drawAll || it->invert_when_selected) {
|
||||||
|
|
|
@ -12,10 +12,17 @@
|
||||||
#include "resources/Font.h"
|
#include "resources/Font.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
|
||||||
DateTimeEditComponent::DateTimeEditComponent(Window *window, bool alignRight, DisplayMode dispMode)
|
DateTimeEditComponent::DateTimeEditComponent(Window* window, bool alignRight, DisplayMode dispMode)
|
||||||
: GuiComponent(window), mEditing(false), mEditIndex(0), mDisplayMode(dispMode), mRelativeUpdateAccumulator(0),
|
: GuiComponent(window)
|
||||||
mColor(0x777777FF), mFont(Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT)), mAlignRight(alignRight),
|
, mEditing(false)
|
||||||
mUppercase(false), mAutoSize(true)
|
, mEditIndex(0)
|
||||||
|
, mDisplayMode(dispMode)
|
||||||
|
, mRelativeUpdateAccumulator(0)
|
||||||
|
, mColor(0x777777FF)
|
||||||
|
, mFont(Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT))
|
||||||
|
, mAlignRight(alignRight)
|
||||||
|
, mUppercase(false)
|
||||||
|
, mAutoSize(true)
|
||||||
{
|
{
|
||||||
updateTextCache();
|
updateTextCache();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,7 @@ void FlexboxComponent::setItemWidth(float value)
|
||||||
}
|
}
|
||||||
float FlexboxComponent::getItemWidth() { return mItemWidth; }
|
float FlexboxComponent::getItemWidth() { return mItemWidth; }
|
||||||
|
|
||||||
void FlexboxComponent::onSizeChanged() {
|
void FlexboxComponent::onSizeChanged() { mLayoutValid = false; }
|
||||||
mLayoutValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlexboxComponent::computeLayout()
|
void FlexboxComponent::computeLayout()
|
||||||
{
|
{
|
||||||
|
@ -95,9 +93,9 @@ void FlexboxComponent::computeLayout()
|
||||||
|
|
||||||
// Pre-compute layout parameters.
|
// Pre-compute layout parameters.
|
||||||
int n = mChildren.size();
|
int n = mChildren.size();
|
||||||
int nLines = std::max(1, (int) std::ceil(n / std::max(1, (int) mItemsPerLine)));
|
int nLines = std::max(1, (int)std::ceil(n / std::max(1, (int)mItemsPerLine)));
|
||||||
float lineWidth =
|
float lineWidth =
|
||||||
(mDirection == "row" ? (maxItemSize.y + mItemMargin.y) : (maxItemSize.x + mItemMargin.x));
|
(mDirection == "row" ? (maxItemSize.y + mItemMargin.y) : (maxItemSize.x + mItemMargin.x));
|
||||||
float anchorXStart = anchorX;
|
float anchorXStart = anchorX;
|
||||||
float anchorYStart = anchorY;
|
float anchorYStart = anchorY;
|
||||||
|
|
||||||
|
@ -106,14 +104,15 @@ void FlexboxComponent::computeLayout()
|
||||||
if (mDirection == "row") {
|
if (mDirection == "row") {
|
||||||
totalSize.x += (mItemMargin.x + mItemWidth) * mItemsPerLine;
|
totalSize.x += (mItemMargin.x + mItemWidth) * mItemsPerLine;
|
||||||
totalSize.y += (mItemMargin.y + maxItemSize.y) * nLines;
|
totalSize.y += (mItemMargin.y + maxItemSize.y) * nLines;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
totalSize.x += (mItemMargin.x + mItemWidth) * nLines;
|
totalSize.x += (mItemMargin.x + mItemWidth) * nLines;
|
||||||
totalSize.y += (mItemMargin.y + maxItemSize.y) * mItemsPerLine;
|
totalSize.y += (mItemMargin.y + maxItemSize.y) * mItemsPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through the children.
|
// Iterate through the children.
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
GuiComponent *child = mChildren[i];
|
GuiComponent* child = mChildren[i];
|
||||||
auto size = child->getSize();
|
auto size = child->getSize();
|
||||||
|
|
||||||
// Top-left anchor position.
|
// Top-left anchor position.
|
||||||
|
@ -132,10 +131,12 @@ void FlexboxComponent::computeLayout()
|
||||||
if (mAlign == ITEM_ALIGN_END) {
|
if (mAlign == ITEM_ALIGN_END) {
|
||||||
x += directionLine.x == 0 ? (maxItemSize.x - size.x) : 0;
|
x += directionLine.x == 0 ? (maxItemSize.x - size.x) : 0;
|
||||||
y += directionLine.y == 0 ? (maxItemSize.y - size.y) : 0;
|
y += directionLine.y == 0 ? (maxItemSize.y - size.y) : 0;
|
||||||
} else if (mAlign == ITEM_ALIGN_CENTER) {
|
}
|
||||||
|
else if (mAlign == ITEM_ALIGN_CENTER) {
|
||||||
x += directionLine.x == 0 ? (maxItemSize.x - size.x) / 2 : 0;
|
x += directionLine.x == 0 ? (maxItemSize.x - size.x) / 2 : 0;
|
||||||
y += directionLine.y == 0 ? (maxItemSize.y - size.y) / 2 : 0;
|
y += directionLine.y == 0 ? (maxItemSize.y - size.y) / 2 : 0;
|
||||||
} else if (mAlign == ITEM_ALIGN_STRETCH && mDirection == "row") {
|
}
|
||||||
|
else if (mAlign == ITEM_ALIGN_STRETCH && mDirection == "row") {
|
||||||
child->setSize(child->getSize().x, maxItemSize.y);
|
child->setSize(child->getSize().x, maxItemSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +150,7 @@ void FlexboxComponent::computeLayout()
|
||||||
child->setPosition(getPosition().x + x, getPosition().y + y);
|
child->setPosition(getPosition().x + x, getPosition().y + y);
|
||||||
|
|
||||||
// Translate anchor.
|
// Translate anchor.
|
||||||
if ((i + 1) % std::max(1, (int) mItemsPerLine) != 0) {
|
if ((i + 1) % std::max(1, (int)mItemsPerLine) != 0) {
|
||||||
// Translate on same line.
|
// Translate on same line.
|
||||||
anchorX += (size.x + mItemMargin.x) * directionLine.x;
|
anchorX += (size.x + mItemMargin.x) * directionLine.x;
|
||||||
anchorY += (size.y + mItemMargin.y) * directionLine.y;
|
anchorY += (size.y + mItemMargin.y) * directionLine.y;
|
||||||
|
@ -159,7 +160,8 @@ void FlexboxComponent::computeLayout()
|
||||||
if (directionRow.x == 0) {
|
if (directionRow.x == 0) {
|
||||||
anchorY += lineWidth * directionRow.y;
|
anchorY += lineWidth * directionRow.y;
|
||||||
anchorX = anchorXStart;
|
anchorX = anchorXStart;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
anchorX += lineWidth * directionRow.x;
|
anchorX += lineWidth * directionRow.x;
|
||||||
anchorY = anchorYStart;
|
anchorY = anchorYStart;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +171,8 @@ void FlexboxComponent::computeLayout()
|
||||||
mLayoutValid = true;
|
mLayoutValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlexboxComponent::render(const glm::mat4& parentTrans) {
|
void FlexboxComponent::render(const glm::mat4& parentTrans)
|
||||||
|
{
|
||||||
if (!isVisible())
|
if (!isVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -37,36 +37,36 @@ void HelpComponent::assignIcons()
|
||||||
":/help/dpad_updown.svg" :
|
":/help/dpad_updown.svg" :
|
||||||
mStyle.mCustomButtons.dpad_updown;
|
mStyle.mCustomButtons.dpad_updown;
|
||||||
sIconPathMap["left/right"] = mStyle.mCustomButtons.dpad_leftright.empty() ?
|
sIconPathMap["left/right"] = mStyle.mCustomButtons.dpad_leftright.empty() ?
|
||||||
":/help/dpad_leftright.svg" :
|
":/help/dpad_leftright.svg" :
|
||||||
mStyle.mCustomButtons.dpad_leftright;
|
mStyle.mCustomButtons.dpad_leftright;
|
||||||
sIconPathMap["up/down/left/right"] = mStyle.mCustomButtons.dpad_all.empty() ?
|
sIconPathMap["up/down/left/right"] = mStyle.mCustomButtons.dpad_all.empty() ?
|
||||||
":/help/dpad_all.svg" :
|
":/help/dpad_all.svg" :
|
||||||
mStyle.mCustomButtons.dpad_all;
|
mStyle.mCustomButtons.dpad_all;
|
||||||
sIconPathMap["thumbstickclick"] = mStyle.mCustomButtons.thumbstick_click.empty() ?
|
sIconPathMap["thumbstickclick"] = mStyle.mCustomButtons.thumbstick_click.empty() ?
|
||||||
":/help/thumbstick_click.svg" :
|
":/help/thumbstick_click.svg" :
|
||||||
mStyle.mCustomButtons.thumbstick_click;
|
mStyle.mCustomButtons.thumbstick_click;
|
||||||
sIconPathMap["l"] = mStyle.mCustomButtons.button_l.empty() ? ":/help/button_l.svg" :
|
sIconPathMap["l"] = mStyle.mCustomButtons.button_l.empty() ? ":/help/button_l.svg" :
|
||||||
mStyle.mCustomButtons.button_l;
|
mStyle.mCustomButtons.button_l;
|
||||||
sIconPathMap["r"] = mStyle.mCustomButtons.button_r.empty() ? ":/help/button_r.svg" :
|
sIconPathMap["r"] = mStyle.mCustomButtons.button_r.empty() ? ":/help/button_r.svg" :
|
||||||
mStyle.mCustomButtons.button_r;
|
mStyle.mCustomButtons.button_r;
|
||||||
sIconPathMap["lr"] = mStyle.mCustomButtons.button_lr.empty() ? ":/help/button_lr.svg" :
|
sIconPathMap["lr"] = mStyle.mCustomButtons.button_lr.empty() ? ":/help/button_lr.svg" :
|
||||||
mStyle.mCustomButtons.button_lr;
|
mStyle.mCustomButtons.button_lr;
|
||||||
sIconPathMap["lt"] = mStyle.mCustomButtons.button_lt.empty() ? ":/help/button_lt.svg" :
|
sIconPathMap["lt"] = mStyle.mCustomButtons.button_lt.empty() ? ":/help/button_lt.svg" :
|
||||||
mStyle.mCustomButtons.button_lt;
|
mStyle.mCustomButtons.button_lt;
|
||||||
sIconPathMap["rt"] = mStyle.mCustomButtons.button_rt.empty() ? ":/help/button_rt.svg" :
|
sIconPathMap["rt"] = mStyle.mCustomButtons.button_rt.empty() ? ":/help/button_rt.svg" :
|
||||||
mStyle.mCustomButtons.button_rt;
|
mStyle.mCustomButtons.button_rt;
|
||||||
|
|
||||||
// These graphics files are custom per controller type.
|
// These graphics files are custom per controller type.
|
||||||
if (controllerType == "snes") {
|
if (controllerType == "snes") {
|
||||||
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_SNES.empty() ?
|
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_SNES.empty() ?
|
||||||
":/help/button_a_SNES.svg" :
|
":/help/button_a_SNES.svg" :
|
||||||
mStyle.mCustomButtons.button_a_SNES;
|
mStyle.mCustomButtons.button_a_SNES;
|
||||||
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_SNES.empty() ?
|
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_SNES.empty() ?
|
||||||
":/help/button_b_SNES.svg" :
|
":/help/button_b_SNES.svg" :
|
||||||
mStyle.mCustomButtons.button_b_SNES;
|
mStyle.mCustomButtons.button_b_SNES;
|
||||||
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_SNES.empty() ?
|
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_SNES.empty() ?
|
||||||
":/help/button_x_SNES.svg" :
|
":/help/button_x_SNES.svg" :
|
||||||
mStyle.mCustomButtons.button_x_SNES;
|
mStyle.mCustomButtons.button_x_SNES;
|
||||||
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_SNES.empty() ?
|
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_SNES.empty() ?
|
||||||
":/help/button_y_SNES.svg" :
|
":/help/button_y_SNES.svg" :
|
||||||
mStyle.mCustomButtons.button_y_SNES;
|
mStyle.mCustomButtons.button_y_SNES;
|
||||||
|
|
|
@ -27,11 +27,23 @@ glm::vec2 ImageComponent::getSize() const
|
||||||
return GuiComponent::getSize() * (mBottomRightCrop - mTopLeftCrop);
|
return GuiComponent::getSize() * (mBottomRightCrop - mTopLeftCrop);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageComponent::ImageComponent(Window *window, bool forceLoad, bool dynamic)
|
ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic)
|
||||||
: GuiComponent(window), mTargetSize({}), mFlipX(false), mFlipY(false), mTargetIsMax(false), mTargetIsMin(false),
|
: GuiComponent(window)
|
||||||
mColorShift(0xFFFFFFFF), mColorShiftEnd(0xFFFFFFFF), mColorGradientHorizontal(true), mFadeOpacity(0),
|
, mTargetSize({})
|
||||||
mFading(false), mForceLoad(forceLoad), mDynamic(dynamic), mRotateByTargetSize(false), mTopLeftCrop({}),
|
, mFlipX(false)
|
||||||
mBottomRightCrop(1.0f, 1.0f)
|
, mFlipY(false)
|
||||||
|
, mTargetIsMax(false)
|
||||||
|
, mTargetIsMin(false)
|
||||||
|
, mColorShift(0xFFFFFFFF)
|
||||||
|
, mColorShiftEnd(0xFFFFFFFF)
|
||||||
|
, mColorGradientHorizontal(true)
|
||||||
|
, mFadeOpacity(0)
|
||||||
|
, mFading(false)
|
||||||
|
, mForceLoad(forceLoad)
|
||||||
|
, mDynamic(dynamic)
|
||||||
|
, mRotateByTargetSize(false)
|
||||||
|
, mTopLeftCrop({})
|
||||||
|
, mBottomRightCrop(1.0f, 1.0f)
|
||||||
{
|
{
|
||||||
updateColors();
|
updateColors();
|
||||||
}
|
}
|
||||||
|
@ -126,7 +138,8 @@ void ImageComponent::resize()
|
||||||
onSizeChanged();
|
onSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::setImage(std::string path, bool tile, bool linearMagnify, bool cacheImage) {
|
void ImageComponent::setImage(std::string path, bool tile, bool linearMagnify, bool cacheImage)
|
||||||
|
{
|
||||||
// Always load bundled graphic resources statically, unless mForceLoad has been set.
|
// Always load bundled graphic resources statically, unless mForceLoad has been set.
|
||||||
// This eliminates annoying texture pop-in problems that would otherwise occur.
|
// This eliminates annoying texture pop-in problems that would otherwise occur.
|
||||||
if (!mForceLoad && (path[0] == ':') && (path[1] == '/')) {
|
if (!mForceLoad && (path[0] == ':') && (path[1] == '/')) {
|
||||||
|
@ -137,11 +150,12 @@ void ImageComponent::setImage(std::string path, bool tile, bool linearMagnify, b
|
||||||
if (mDefaultPath.empty() || !ResourceManager::getInstance()->fileExists(mDefaultPath))
|
if (mDefaultPath.empty() || !ResourceManager::getInstance()->fileExists(mDefaultPath))
|
||||||
mTexture.reset();
|
mTexture.reset();
|
||||||
else
|
else
|
||||||
mTexture =
|
mTexture = TextureResource::get(mDefaultPath, tile, mForceLoad, mDynamic, linearMagnify,
|
||||||
TextureResource::get(mDefaultPath, tile, mForceLoad, mDynamic, linearMagnify, 1.0f, cacheImage);
|
1.0f, cacheImage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mTexture = TextureResource::get(path, tile, mForceLoad, mDynamic, linearMagnify, 1.0f, cacheImage);
|
mTexture =
|
||||||
|
TextureResource::get(path, tile, mForceLoad, mDynamic, linearMagnify, 1.0f, cacheImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
resize();
|
resize();
|
||||||
|
|
|
@ -14,9 +14,10 @@
|
||||||
|
|
||||||
class TextureResource;
|
class TextureResource;
|
||||||
|
|
||||||
class ImageComponent : public GuiComponent {
|
class ImageComponent : public GuiComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
ImageComponent(Window *window, bool forceLoad = false, bool dynamic = true);
|
ImageComponent(Window* window, bool forceLoad = false, bool dynamic = true);
|
||||||
|
|
||||||
virtual ~ImageComponent() noexcept {};
|
virtual ~ImageComponent() noexcept {};
|
||||||
|
|
||||||
|
@ -24,13 +25,16 @@ public:
|
||||||
|
|
||||||
// Loads the image at the given filepath. Will tile if tile is true (retrieves texture
|
// Loads the image at the given filepath. Will tile if tile is true (retrieves texture
|
||||||
// as tiling, creates vertices accordingly).
|
// as tiling, creates vertices accordingly).
|
||||||
void setImage(std::string path, bool tile = false, bool linearMagnify = false, bool cacheSVG = false);
|
void setImage(std::string path,
|
||||||
|
bool tile = false,
|
||||||
|
bool linearMagnify = false,
|
||||||
|
bool cacheSVG = false);
|
||||||
|
|
||||||
// Loads an image from memory.
|
// Loads an image from memory.
|
||||||
void setImage(const char *data, size_t length, bool tile = false);
|
void setImage(const char* data, size_t length, bool tile = false);
|
||||||
|
|
||||||
// Use an already existing texture.
|
// Use an already existing texture.
|
||||||
void setImage(const std::shared_ptr<TextureResource> &texture);
|
void setImage(const std::shared_ptr<TextureResource>& texture);
|
||||||
|
|
||||||
void onSizeChanged() override { updateVertices(); }
|
void onSizeChanged() override { updateVertices(); }
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ GuiInputConfig::GuiInputConfig(Window* window,
|
||||||
};
|
};
|
||||||
|
|
||||||
buttons.push_back(
|
buttons.push_back(
|
||||||
std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [okFunction] { okFunction(); }));
|
std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [okFunction] { okFunction(); }));
|
||||||
|
|
||||||
mButtonGrid = makeButtonGrid(mWindow, buttons);
|
mButtonGrid = makeButtonGrid(mWindow, buttons);
|
||||||
mGrid.setEntry(mButtonGrid, glm::ivec2{0, 6}, true, false);
|
mGrid.setEntry(mButtonGrid, glm::ivec2{0, 6}, true, false);
|
||||||
|
|
|
@ -15,18 +15,22 @@
|
||||||
#define HORIZONTAL_PADDING_PX 20.0f
|
#define HORIZONTAL_PADDING_PX 20.0f
|
||||||
|
|
||||||
GuiMsgBox::GuiMsgBox(Window* window,
|
GuiMsgBox::GuiMsgBox(Window* window,
|
||||||
const HelpStyle &helpstyle,
|
const HelpStyle& helpstyle,
|
||||||
const std::string &text,
|
const std::string& text,
|
||||||
const std::string &name1,
|
const std::string& name1,
|
||||||
const std::function<void()> &func1,
|
const std::function<void()>& func1,
|
||||||
const std::string &name2,
|
const std::string& name2,
|
||||||
const std::function<void()> &func2,
|
const std::function<void()>& func2,
|
||||||
const std::string &name3,
|
const std::string& name3,
|
||||||
const std::function<void()> &func3,
|
const std::function<void()>& func3,
|
||||||
bool disableBackButton,
|
bool disableBackButton,
|
||||||
bool deleteOnButtonPress)
|
bool deleteOnButtonPress)
|
||||||
: GuiComponent(window), mBackground(window, ":/graphics/frame.svg"), mGrid(window, glm::ivec2{1, 2}),
|
: GuiComponent(window)
|
||||||
mHelpStyle(helpstyle), mDisableBackButton(disableBackButton), mDeleteOnButtonPress(deleteOnButtonPress)
|
, mBackground(window, ":/graphics/frame.svg")
|
||||||
|
, mGrid(window, glm::ivec2{1, 2})
|
||||||
|
, mHelpStyle(helpstyle)
|
||||||
|
, mDisableBackButton(disableBackButton)
|
||||||
|
, mDeleteOnButtonPress(deleteOnButtonPress)
|
||||||
{
|
{
|
||||||
// Adjust the width relative to the aspect ratio of the screen to make the GUI look coherent
|
// Adjust the width relative to the aspect ratio of the screen to make the GUI look coherent
|
||||||
// regardless of screen type. The 1.778 aspect ratio value is the 16:9 reference.
|
// regardless of screen type. The 1.778 aspect ratio value is the 16:9 reference.
|
||||||
|
|
|
@ -74,33 +74,47 @@ std::vector<std::vector<const char *>> kbLastRowLoad{
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
Window *window,
|
Window* window,
|
||||||
const HelpStyle &helpstyle,
|
const HelpStyle& helpstyle,
|
||||||
const std::string &title,
|
const std::string& title,
|
||||||
const std::string &initValue,
|
const std::string& initValue,
|
||||||
const std::function<void(const std::string &)> &okCallback,
|
const std::function<void(const std::string&)>& okCallback,
|
||||||
bool multiLine,
|
bool multiLine,
|
||||||
const std::string &acceptBtnHelpText,
|
const std::string& acceptBtnHelpText,
|
||||||
const std::string &saveConfirmationText,
|
const std::string& saveConfirmationText,
|
||||||
const std::string &infoString,
|
const std::string& infoString,
|
||||||
const std::string &defaultValue,
|
const std::string& defaultValue,
|
||||||
const std::string &loadBtnHelpText,
|
const std::string& loadBtnHelpText,
|
||||||
const std::string &clearBtnHelpText,
|
const std::string& clearBtnHelpText,
|
||||||
const std::string &cancelBtnHelpText)
|
const std::string& cancelBtnHelpText)
|
||||||
: GuiComponent{window}, mBackground{window, ":/graphics/frame.svg"},
|
: GuiComponent{window}
|
||||||
mGrid{window, glm::ivec2{1, (infoString != "" && defaultValue != "" ? 8 : 6)}}, mHelpStyle{helpstyle},
|
, mBackground{window, ":/graphics/frame.svg"}
|
||||||
mInitValue{initValue}, mAcceptBtnHelpText{acceptBtnHelpText}, mSaveConfirmationText{saveConfirmationText},
|
, mGrid{window, glm::ivec2{1, (infoString != "" && defaultValue != "" ? 8 : 6)}}
|
||||||
mLoadBtnHelpText{loadBtnHelpText}, mClearBtnHelpText{clearBtnHelpText}, mCancelBtnHelpText{cancelBtnHelpText},
|
, mHelpStyle{helpstyle}
|
||||||
mOkCallback{okCallback}, mMultiLine{multiLine}, mComplexMode{(infoString != "" && defaultValue != "")},
|
, mInitValue{initValue}
|
||||||
mDeleteRepeat{false}, mShift{false}, mAlt{false}, mDeleteRepeatTimer{0}, mNavigationRepeatTimer{0},
|
, mAcceptBtnHelpText{acceptBtnHelpText}
|
||||||
mNavigationRepeatDirX{0}, mNavigationRepeatDirY{0} {
|
, mSaveConfirmationText{saveConfirmationText}
|
||||||
|
, mLoadBtnHelpText{loadBtnHelpText}
|
||||||
|
, mClearBtnHelpText{clearBtnHelpText}
|
||||||
|
, mCancelBtnHelpText{cancelBtnHelpText}
|
||||||
|
, mOkCallback{okCallback}
|
||||||
|
, mMultiLine{multiLine}
|
||||||
|
, mComplexMode{(infoString != "" && defaultValue != "")}
|
||||||
|
, mDeleteRepeat{false}
|
||||||
|
, mShift{false}
|
||||||
|
, mAlt{false}
|
||||||
|
, mDeleteRepeatTimer{0}
|
||||||
|
, mNavigationRepeatTimer{0}
|
||||||
|
, mNavigationRepeatDirX{0}
|
||||||
|
, mNavigationRepeatDirY{0}
|
||||||
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
|
||||||
mTitle = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(title),
|
mTitle = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(title),
|
||||||
Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER);
|
Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER);
|
||||||
|
|
||||||
std::vector<std::vector<const char *>> kbLayout;
|
std::vector<std::vector<const char*>> kbLayout;
|
||||||
|
|
||||||
// At the moment there is only the US keyboard layout available.
|
// At the moment there is only the US keyboard layout available.
|
||||||
kbLayout.insert(kbLayout.cend(), kbBaseUS.cbegin(), kbBaseUS.cend());
|
kbLayout.insert(kbLayout.cend(), kbBaseUS.cbegin(), kbBaseUS.cend());
|
||||||
|
@ -114,7 +128,7 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
mHorizontalKeyCount = static_cast<int>(kbLayout[0].size());
|
mHorizontalKeyCount = static_cast<int>(kbLayout[0].size());
|
||||||
|
|
||||||
mKeyboardGrid = std::make_shared<ComponentGrid>(
|
mKeyboardGrid = std::make_shared<ComponentGrid>(
|
||||||
mWindow, glm::ivec2(mHorizontalKeyCount, static_cast<int>(kbLayout.size()) / 3));
|
mWindow, glm::ivec2(mHorizontalKeyCount, static_cast<int>(kbLayout.size()) / 3));
|
||||||
|
|
||||||
mText = std::make_shared<TextEditComponent>(mWindow);
|
mText = std::make_shared<TextEditComponent>(mWindow);
|
||||||
mText->setValue(initValue);
|
mText->setValue(initValue);
|
||||||
|
@ -129,11 +143,11 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
|
|
||||||
if (mComplexMode) {
|
if (mComplexMode) {
|
||||||
mInfoString = std::make_shared<TextComponent>(
|
mInfoString = std::make_shared<TextComponent>(
|
||||||
mWindow, infoString, Font::get(FONT_SIZE_MEDIUM), 0x555555FF, ALIGN_CENTER);
|
mWindow, infoString, Font::get(FONT_SIZE_MEDIUM), 0x555555FF, ALIGN_CENTER);
|
||||||
mGrid.setEntry(mInfoString, glm::ivec2{0, yPos}, false, true);
|
mGrid.setEntry(mInfoString, glm::ivec2{0, yPos}, false, true);
|
||||||
|
|
||||||
mDefaultValue = std::make_shared<TextComponent>(
|
mDefaultValue = std::make_shared<TextComponent>(
|
||||||
mWindow, defaultValue, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
mWindow, defaultValue, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
||||||
mGrid.setEntry(mDefaultValue, glm::ivec2{0, yPos + 1}, false, true);
|
mGrid.setEntry(mDefaultValue, glm::ivec2{0, yPos + 1}, false, true);
|
||||||
yPos += 2;
|
yPos += 2;
|
||||||
}
|
}
|
||||||
|
@ -164,17 +178,20 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
upper = DELETE_SYMBOL;
|
upper = DELETE_SYMBOL;
|
||||||
alted = DELETE_SYMBOL;
|
alted = DELETE_SYMBOL;
|
||||||
altshifted = DELETE_SYMBOL;
|
altshifted = DELETE_SYMBOL;
|
||||||
} else if (lower == "OK") {
|
}
|
||||||
|
else if (lower == "OK") {
|
||||||
lower = OK_SYMBOL;
|
lower = OK_SYMBOL;
|
||||||
upper = OK_SYMBOL;
|
upper = OK_SYMBOL;
|
||||||
alted = OK_SYMBOL;
|
alted = OK_SYMBOL;
|
||||||
altshifted = OK_SYMBOL;
|
altshifted = OK_SYMBOL;
|
||||||
} else if (lower == "SPACE") {
|
}
|
||||||
|
else if (lower == "SPACE") {
|
||||||
lower = " ";
|
lower = " ";
|
||||||
upper = " ";
|
upper = " ";
|
||||||
alted = " ";
|
alted = " ";
|
||||||
altshifted = " ";
|
altshifted = " ";
|
||||||
} else if (lower != "SHIFT" && lower.length() > 1) {
|
}
|
||||||
|
else if (lower != "SHIFT" && lower.length() > 1) {
|
||||||
lower = (lower.c_str());
|
lower = (lower.c_str());
|
||||||
upper = (upper.c_str());
|
upper = (upper.c_str());
|
||||||
alted = (alted.c_str());
|
alted = (alted.c_str());
|
||||||
|
@ -183,19 +200,21 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
|
|
||||||
if (lower == "SHIFT") {
|
if (lower == "SHIFT") {
|
||||||
mShiftButton = std::make_shared<ButtonComponent>(
|
mShiftButton = std::make_shared<ButtonComponent>(
|
||||||
mWindow, (SHIFT_SYMBOL), ("SHIFT"), [this] { shiftKeys(); }, false, true);
|
mWindow, (SHIFT_SYMBOL), ("SHIFT"), [this] { shiftKeys(); }, false, true);
|
||||||
button = mShiftButton;
|
button = mShiftButton;
|
||||||
} else if (lower == "ALT") {
|
}
|
||||||
|
else if (lower == "ALT") {
|
||||||
mAltButton = std::make_shared<ButtonComponent>(
|
mAltButton = std::make_shared<ButtonComponent>(
|
||||||
mWindow, (ALT_SYMBOL), ("ALT"), [this] { altKeys(); }, false, true);
|
mWindow, (ALT_SYMBOL), ("ALT"), [this] { altKeys(); }, false, true);
|
||||||
button = mAltButton;
|
button = mAltButton;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
button = makeButton(lower, upper, alted, altshifted);
|
button = makeButton(lower, upper, alted, altshifted);
|
||||||
}
|
}
|
||||||
|
|
||||||
button->setPadding(
|
button->setPadding(
|
||||||
glm::vec4(BUTTON_GRID_HORIZ_PADDING / 4.0f, BUTTON_GRID_HORIZ_PADDING / 4.0f,
|
glm::vec4(BUTTON_GRID_HORIZ_PADDING / 4.0f, BUTTON_GRID_HORIZ_PADDING / 4.0f,
|
||||||
BUTTON_GRID_HORIZ_PADDING / 4.0f, BUTTON_GRID_HORIZ_PADDING / 4.0f));
|
BUTTON_GRID_HORIZ_PADDING / 4.0f, BUTTON_GRID_HORIZ_PADDING / 4.0f));
|
||||||
buttons.push_back(button);
|
buttons.push_back(button);
|
||||||
|
|
||||||
int colSpan = 1;
|
int colSpan = 1;
|
||||||
|
@ -233,13 +252,14 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
mText->setSize(0.0f, textHeight);
|
mText->setSize(0.0f, textHeight);
|
||||||
|
|
||||||
// If attempting to navigate beyond the edge of the keyboard grid, then wrap around.
|
// If attempting to navigate beyond the edge of the keyboard grid, then wrap around.
|
||||||
mGrid.setPastBoundaryCallback([this, kbLayout](InputConfig *config, Input input) -> bool {
|
mGrid.setPastBoundaryCallback([this, kbLayout](InputConfig* config, Input input) -> bool {
|
||||||
if (config->isMappedLike("left", input)) {
|
if (config->isMappedLike("left", input)) {
|
||||||
if (mGrid.getSelectedComponent() == mKeyboardGrid) {
|
if (mGrid.getSelectedComponent() == mKeyboardGrid) {
|
||||||
mKeyboardGrid->moveCursorTo(mHorizontalKeyCount - 1, -1, true);
|
mKeyboardGrid->moveCursorTo(mHorizontalKeyCount - 1, -1, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (config->isMappedLike("right", input)) {
|
}
|
||||||
|
else if (config->isMappedLike("right", input)) {
|
||||||
if (mGrid.getSelectedComponent() == mKeyboardGrid) {
|
if (mGrid.getSelectedComponent() == mKeyboardGrid) {
|
||||||
mKeyboardGrid->moveCursorTo(0, -1);
|
mKeyboardGrid->moveCursorTo(0, -1);
|
||||||
return true;
|
return true;
|
||||||
|
@ -259,7 +279,8 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
|
|
||||||
setPosition((static_cast<float>(Renderer::getScreenWidth()) - mSize.x) / 2.0f,
|
setPosition((static_cast<float>(Renderer::getScreenWidth()) - mSize.x) / 2.0f,
|
||||||
(static_cast<float>(Renderer::getScreenHeight()) - mSize.y) / 2.0f);
|
(static_cast<float>(Renderer::getScreenHeight()) - mSize.y) / 2.0f);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (mComplexMode)
|
if (mComplexMode)
|
||||||
setSize(width, KEYBOARD_HEIGHT + mDefaultValue->getSize().y * 3.0f);
|
setSize(width, KEYBOARD_HEIGHT + mDefaultValue->getSize().y * 3.0f);
|
||||||
else
|
else
|
||||||
|
@ -270,7 +291,8 @@ GuiTextEditKeyboardPopup::GuiTextEditKeyboardPopup(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::onSizeChanged() {
|
void GuiTextEditKeyboardPopup::onSizeChanged()
|
||||||
|
{
|
||||||
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
|
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
|
||||||
mText->setSize(mSize.x - KEYBOARD_PADDINGX - KEYBOARD_PADDINGX, mText->getSize().y);
|
mText->setSize(mSize.x - KEYBOARD_PADDINGX - KEYBOARD_PADDINGX, mText->getSize().y);
|
||||||
|
|
||||||
|
@ -281,7 +303,8 @@ void GuiTextEditKeyboardPopup::onSizeChanged() {
|
||||||
mGrid.setRowHeightPerc(1, (mInfoString->getSize().y * 0.6f) / mSize.y);
|
mGrid.setRowHeightPerc(1, (mInfoString->getSize().y * 0.6f) / mSize.y);
|
||||||
mGrid.setRowHeightPerc(2, (mDefaultValue->getSize().y * 1.6f) / mSize.y);
|
mGrid.setRowHeightPerc(2, (mDefaultValue->getSize().y * 1.6f) / mSize.y);
|
||||||
mGrid.setRowHeightPerc(1, (mText->getSize().y * 1.0f) / mSize.y);
|
mGrid.setRowHeightPerc(1, (mText->getSize().y * 1.0f) / mSize.y);
|
||||||
} else if (mMultiLine) {
|
}
|
||||||
|
else if (mMultiLine) {
|
||||||
mGrid.setRowHeightPerc(1, (mText->getSize().y * 1.15f) / mSize.y);
|
mGrid.setRowHeightPerc(1, (mText->getSize().y * 1.15f) / mSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +319,8 @@ void GuiTextEditKeyboardPopup::onSizeChanged() {
|
||||||
mKeyboardGrid->setPosition(KEYBOARD_PADDINGX, pos.y);
|
mKeyboardGrid->setPosition(KEYBOARD_PADDINGX, pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
bool GuiTextEditKeyboardPopup::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
// Enter/return key or numpad enter key accepts the changes.
|
// Enter/return key or numpad enter key accepts the changes.
|
||||||
if (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() && !mMultiLine &&
|
if (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() && !mMultiLine &&
|
||||||
input.value && (input.id == SDLK_RETURN || input.id == SDLK_KP_ENTER)) {
|
input.value && (input.id == SDLK_RETURN || input.id == SDLK_KP_ENTER)) {
|
||||||
|
@ -304,7 +328,7 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Dito for the A button if using a controller.
|
// Dito for the A button if using a controller.
|
||||||
else if (config->getDeviceId() != DEVICE_KEYBOARD && mText->isEditing() &&
|
else if (config->getDeviceId() != DEVICE_KEYBOARD && mText->isEditing() &&
|
||||||
config->isMappedTo("a", input) && input.value) {
|
config->isMappedTo("a", input) && input.value) {
|
||||||
this->mOkCallback(mText->getValue());
|
this->mOkCallback(mText->getValue());
|
||||||
|
@ -330,18 +354,19 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
if (mText->getValue() != mInitValue) {
|
if (mText->getValue() != mInitValue) {
|
||||||
// Changes were made, ask if the user wants to save them.
|
// Changes were made, ask if the user wants to save them.
|
||||||
mWindow->pushGui(new GuiMsgBox(
|
mWindow->pushGui(new GuiMsgBox(
|
||||||
mWindow, mHelpStyle, mSaveConfirmationText, "YES",
|
mWindow, mHelpStyle, mSaveConfirmationText, "YES",
|
||||||
[this] {
|
[this] {
|
||||||
this->mOkCallback(mText->getValue());
|
this->mOkCallback(mText->getValue());
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
"NO",
|
"NO",
|
||||||
[this] {
|
[this] {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +399,8 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
|
|
||||||
if (!editing)
|
if (!editing)
|
||||||
mText->stopEditing();
|
mText->stopEditing();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mDeleteRepeat = false;
|
mDeleteRepeat = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -400,7 +426,8 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
if (input.value) {
|
if (input.value) {
|
||||||
mNavigationRepeatDirX = -1;
|
mNavigationRepeatDirX = -1;
|
||||||
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mNavigationRepeatDirX = 0;
|
mNavigationRepeatDirX = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,7 +436,8 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
if (input.value) {
|
if (input.value) {
|
||||||
mNavigationRepeatDirX = 1;
|
mNavigationRepeatDirX = 1;
|
||||||
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mNavigationRepeatDirX = 0;
|
mNavigationRepeatDirX = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +446,8 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
if (input.value) {
|
if (input.value) {
|
||||||
mNavigationRepeatDirY = -1;
|
mNavigationRepeatDirY = -1;
|
||||||
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mNavigationRepeatDirY = 0;
|
mNavigationRepeatDirY = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,7 +456,8 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
if (input.value) {
|
if (input.value) {
|
||||||
mNavigationRepeatDirY = 1;
|
mNavigationRepeatDirY = 1;
|
||||||
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
mNavigationRepeatTimer = -(NAVIGATION_REPEAT_START_DELAY - NAVIGATION_REPEAT_SPEED);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mNavigationRepeatDirY = 0;
|
mNavigationRepeatDirY = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,19 +468,22 @@ bool GuiTextEditKeyboardPopup::input(InputConfig *config, Input input) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::update(int deltaTime) {
|
void GuiTextEditKeyboardPopup::update(int deltaTime)
|
||||||
|
{
|
||||||
updateNavigationRepeat(deltaTime);
|
updateNavigationRepeat(deltaTime);
|
||||||
updateDeleteRepeat(deltaTime);
|
updateDeleteRepeat(deltaTime);
|
||||||
GuiComponent::update(deltaTime);
|
GuiComponent::update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HelpPrompt> GuiTextEditKeyboardPopup::getHelpPrompts() {
|
std::vector<HelpPrompt> GuiTextEditKeyboardPopup::getHelpPrompts()
|
||||||
|
{
|
||||||
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
|
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
|
||||||
|
|
||||||
if (!mText->isEditing()) {
|
if (!mText->isEditing()) {
|
||||||
prompts.push_back(HelpPrompt("lt", "shift"));
|
prompts.push_back(HelpPrompt("lt", "shift"));
|
||||||
prompts.push_back(HelpPrompt("rt", "alt"));
|
prompts.push_back(HelpPrompt("rt", "alt"));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
prompts.push_back(HelpPrompt("a", mAcceptBtnHelpText));
|
prompts.push_back(HelpPrompt("a", mAcceptBtnHelpText));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +513,8 @@ std::vector<HelpPrompt> GuiTextEditKeyboardPopup::getHelpPrompts() {
|
||||||
return prompts;
|
return prompts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::updateDeleteRepeat(int deltaTime) {
|
void GuiTextEditKeyboardPopup::updateDeleteRepeat(int deltaTime)
|
||||||
|
{
|
||||||
if (!mDeleteRepeat)
|
if (!mDeleteRepeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -500,7 +534,8 @@ void GuiTextEditKeyboardPopup::updateDeleteRepeat(int deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::updateNavigationRepeat(int deltaTime) {
|
void GuiTextEditKeyboardPopup::updateNavigationRepeat(int deltaTime)
|
||||||
|
{
|
||||||
if (mNavigationRepeatDirX == 0 && mNavigationRepeatDirY == 0)
|
if (mNavigationRepeatDirX == 0 && mNavigationRepeatDirY == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -527,13 +562,15 @@ void GuiTextEditKeyboardPopup::updateNavigationRepeat(int deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::shiftKeys() {
|
void GuiTextEditKeyboardPopup::shiftKeys()
|
||||||
|
{
|
||||||
mShift = !mShift;
|
mShift = !mShift;
|
||||||
|
|
||||||
if (mShift) {
|
if (mShift) {
|
||||||
mShiftButton->setFlatColorFocused(0xFF2222FF);
|
mShiftButton->setFlatColorFocused(0xFF2222FF);
|
||||||
mShiftButton->setFlatColorUnfocused(0xFF2222FF);
|
mShiftButton->setFlatColorUnfocused(0xFF2222FF);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mShiftButton->setFlatColorFocused(0x878787FF);
|
mShiftButton->setFlatColorFocused(0x878787FF);
|
||||||
mShiftButton->setFlatColorUnfocused(0x60606025);
|
mShiftButton->setFlatColorUnfocused(0x60606025);
|
||||||
}
|
}
|
||||||
|
@ -547,9 +584,10 @@ void GuiTextEditKeyboardPopup::shiftKeys() {
|
||||||
if (mAlt) {
|
if (mAlt) {
|
||||||
altKeys();
|
altKeys();
|
||||||
altKeys();
|
altKeys();
|
||||||
} else {
|
}
|
||||||
for (auto &kb: mKeyboardButtons) {
|
else {
|
||||||
const std::string &text = mShift ? kb.shiftedKey : kb.key;
|
for (auto& kb : mKeyboardButtons) {
|
||||||
|
const std::string& text = mShift ? kb.shiftedKey : kb.key;
|
||||||
auto sz = kb.button->getSize();
|
auto sz = kb.button->getSize();
|
||||||
kb.button->setText(text, text, false);
|
kb.button->setText(text, text, false);
|
||||||
kb.button->setSize(sz);
|
kb.button->setSize(sz);
|
||||||
|
@ -557,13 +595,15 @@ void GuiTextEditKeyboardPopup::shiftKeys() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::altKeys() {
|
void GuiTextEditKeyboardPopup::altKeys()
|
||||||
|
{
|
||||||
mAlt = !mAlt;
|
mAlt = !mAlt;
|
||||||
|
|
||||||
if (mAlt) {
|
if (mAlt) {
|
||||||
mAltButton->setFlatColorFocused(0xFF2222FF);
|
mAltButton->setFlatColorFocused(0xFF2222FF);
|
||||||
mAltButton->setFlatColorUnfocused(0xFF2222FF);
|
mAltButton->setFlatColorUnfocused(0xFF2222FF);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mAltButton->setFlatColorFocused(0x878787FF);
|
mAltButton->setFlatColorFocused(0x878787FF);
|
||||||
mAltButton->setFlatColorUnfocused(0x60606025);
|
mAltButton->setFlatColorUnfocused(0x60606025);
|
||||||
}
|
}
|
||||||
|
@ -577,9 +617,10 @@ void GuiTextEditKeyboardPopup::altKeys() {
|
||||||
if (mShift) {
|
if (mShift) {
|
||||||
shiftKeys();
|
shiftKeys();
|
||||||
shiftKeys();
|
shiftKeys();
|
||||||
} else {
|
}
|
||||||
for (auto &kb: mKeyboardButtons) {
|
else {
|
||||||
const std::string &text = mAlt ? kb.altedKey : kb.key;
|
for (auto& kb : mKeyboardButtons) {
|
||||||
|
const std::string& text = mAlt ? kb.altedKey : kb.key;
|
||||||
auto sz = kb.button->getSize();
|
auto sz = kb.button->getSize();
|
||||||
kb.button->setText(text, text, false);
|
kb.button->setText(text, text, false);
|
||||||
kb.button->setSize(sz);
|
kb.button->setSize(sz);
|
||||||
|
@ -587,9 +628,10 @@ void GuiTextEditKeyboardPopup::altKeys() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditKeyboardPopup::altShiftKeys() {
|
void GuiTextEditKeyboardPopup::altShiftKeys()
|
||||||
for (auto &kb: mKeyboardButtons) {
|
{
|
||||||
const std::string &text = kb.altshiftedKey;
|
for (auto& kb : mKeyboardButtons) {
|
||||||
|
const std::string& text = kb.altshiftedKey;
|
||||||
auto sz = kb.button->getSize();
|
auto sz = kb.button->getSize();
|
||||||
kb.button->setText(text, text, false);
|
kb.button->setText(text, text, false);
|
||||||
kb.button->setSize(sz);
|
kb.button->setSize(sz);
|
||||||
|
@ -597,56 +639,62 @@ void GuiTextEditKeyboardPopup::altShiftKeys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ButtonComponent> GuiTextEditKeyboardPopup::makeButton(
|
std::shared_ptr<ButtonComponent> GuiTextEditKeyboardPopup::makeButton(
|
||||||
const std::string &key,
|
const std::string& key,
|
||||||
const std::string &shiftedKey,
|
const std::string& shiftedKey,
|
||||||
const std::string &altedKey,
|
const std::string& altedKey,
|
||||||
const std::string &altshiftedKey) {
|
const std::string& altshiftedKey)
|
||||||
|
{
|
||||||
std::shared_ptr<ButtonComponent> button = std::make_shared<ButtonComponent>(
|
std::shared_ptr<ButtonComponent> button = std::make_shared<ButtonComponent>(
|
||||||
mWindow, key, key,
|
mWindow, key, key,
|
||||||
[this, key, shiftedKey, altedKey, altshiftedKey] {
|
[this, key, shiftedKey, altedKey, altshiftedKey] {
|
||||||
if (key == (OK_SYMBOL) || key.find("OK") != std::string::npos) {
|
if (key == (OK_SYMBOL) || key.find("OK") != std::string::npos) {
|
||||||
mOkCallback(mText->getValue());
|
mOkCallback(mText->getValue());
|
||||||
delete this;
|
delete this;
|
||||||
return;
|
return;
|
||||||
} else if (key == (DELETE_SYMBOL) || key == "DEL") {
|
}
|
||||||
mText->startEditing();
|
else if (key == (DELETE_SYMBOL) || key == "DEL") {
|
||||||
mText->textInput("\b");
|
|
||||||
mText->stopEditing();
|
|
||||||
return;
|
|
||||||
} else if (key == "SPACE" || key == " ") {
|
|
||||||
mText->startEditing();
|
|
||||||
mText->textInput(" ");
|
|
||||||
mText->stopEditing();
|
|
||||||
return;
|
|
||||||
} else if (key == "LOAD") {
|
|
||||||
mText->setValue(mDefaultValue->getValue());
|
|
||||||
mText->setCursor(mDefaultValue->getValue().size());
|
|
||||||
return;
|
|
||||||
} else if (key == "CLEAR") {
|
|
||||||
mText->setValue("");
|
|
||||||
return;
|
|
||||||
} else if (key == "CANCEL") {
|
|
||||||
delete this;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAlt && altedKey.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mText->startEditing();
|
mText->startEditing();
|
||||||
|
mText->textInput("\b");
|
||||||
if (mShift && mAlt)
|
|
||||||
mText->textInput(altshiftedKey.c_str());
|
|
||||||
else if (mAlt)
|
|
||||||
mText->textInput(altedKey.c_str());
|
|
||||||
else if (mShift)
|
|
||||||
mText->textInput(shiftedKey.c_str());
|
|
||||||
else
|
|
||||||
mText->textInput(key.c_str());
|
|
||||||
|
|
||||||
mText->stopEditing();
|
mText->stopEditing();
|
||||||
},
|
return;
|
||||||
false, true);
|
}
|
||||||
|
else if (key == "SPACE" || key == " ") {
|
||||||
|
mText->startEditing();
|
||||||
|
mText->textInput(" ");
|
||||||
|
mText->stopEditing();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (key == "LOAD") {
|
||||||
|
mText->setValue(mDefaultValue->getValue());
|
||||||
|
mText->setCursor(mDefaultValue->getValue().size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (key == "CLEAR") {
|
||||||
|
mText->setValue("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (key == "CANCEL") {
|
||||||
|
delete this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAlt && altedKey.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mText->startEditing();
|
||||||
|
|
||||||
|
if (mShift && mAlt)
|
||||||
|
mText->textInput(altshiftedKey.c_str());
|
||||||
|
else if (mAlt)
|
||||||
|
mText->textInput(altedKey.c_str());
|
||||||
|
else if (mShift)
|
||||||
|
mText->textInput(shiftedKey.c_str());
|
||||||
|
else
|
||||||
|
mText->textInput(key.c_str());
|
||||||
|
|
||||||
|
mText->stopEditing();
|
||||||
|
},
|
||||||
|
false, true);
|
||||||
|
|
||||||
KeyboardButton kb(button, key, shiftedKey, altedKey, altshiftedKey);
|
KeyboardButton kb(button, key, shiftedKey, altedKey, altshiftedKey);
|
||||||
mKeyboardButtons.push_back(kb);
|
mKeyboardButtons.push_back(kb);
|
||||||
|
|
|
@ -15,25 +15,26 @@
|
||||||
#include "components/ComponentGrid.h"
|
#include "components/ComponentGrid.h"
|
||||||
#include "components/TextEditComponent.h"
|
#include "components/TextEditComponent.h"
|
||||||
|
|
||||||
class GuiTextEditKeyboardPopup : public GuiComponent {
|
class GuiTextEditKeyboardPopup : public GuiComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
GuiTextEditKeyboardPopup(Window *window,
|
GuiTextEditKeyboardPopup(Window* window,
|
||||||
const HelpStyle &helpstyle,
|
const HelpStyle& helpstyle,
|
||||||
const std::string &title,
|
const std::string& title,
|
||||||
const std::string &initValue,
|
const std::string& initValue,
|
||||||
const std::function<void(const std::string &)> &okCallback,
|
const std::function<void(const std::string&)>& okCallback,
|
||||||
bool multiLine,
|
bool multiLine,
|
||||||
const std::string &acceptBtnHelpText = "OK",
|
const std::string& acceptBtnHelpText = "OK",
|
||||||
const std::string &saveConfirmationText = "SAVE CHANGES?",
|
const std::string& saveConfirmationText = "SAVE CHANGES?",
|
||||||
const std::string &infoString = "",
|
const std::string& infoString = "",
|
||||||
const std::string &defaultValue = "",
|
const std::string& defaultValue = "",
|
||||||
const std::string &loadBtnHelpText = "LOAD DEFAULT",
|
const std::string& loadBtnHelpText = "LOAD DEFAULT",
|
||||||
const std::string &clearBtnHelpText = "CLEAR",
|
const std::string& clearBtnHelpText = "CLEAR",
|
||||||
const std::string &cancelBtnHelpText = "DISCARD CHANGES");
|
const std::string& cancelBtnHelpText = "DISCARD CHANGES");
|
||||||
|
|
||||||
void onSizeChanged() override;
|
void onSizeChanged() override;
|
||||||
|
|
||||||
bool input(InputConfig *config, Input input) override;
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
|
|
||||||
|
@ -42,7 +43,8 @@ public:
|
||||||
HelpStyle getHelpStyle() override { return mHelpStyle; }
|
HelpStyle getHelpStyle() override { return mHelpStyle; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class KeyboardButton {
|
class KeyboardButton
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<ButtonComponent> button;
|
std::shared_ptr<ButtonComponent> button;
|
||||||
const std::string key;
|
const std::string key;
|
||||||
|
@ -51,11 +53,15 @@ private:
|
||||||
const std::string altshiftedKey;
|
const std::string altshiftedKey;
|
||||||
|
|
||||||
KeyboardButton(const std::shared_ptr<ButtonComponent> b,
|
KeyboardButton(const std::shared_ptr<ButtonComponent> b,
|
||||||
const std::string &k,
|
const std::string& k,
|
||||||
const std::string &sk,
|
const std::string& sk,
|
||||||
const std::string &ak,
|
const std::string& ak,
|
||||||
const std::string &ask)
|
const std::string& ask)
|
||||||
: button{b}, key{k}, shiftedKey{sk}, altedKey{ak}, altshiftedKey{ask} {};
|
: button{b}
|
||||||
|
, key{k}
|
||||||
|
, shiftedKey{sk}
|
||||||
|
, altedKey{ak}
|
||||||
|
, altshiftedKey{ask} {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void updateDeleteRepeat(int deltaTime);
|
void updateDeleteRepeat(int deltaTime);
|
||||||
|
@ -68,10 +74,10 @@ private:
|
||||||
|
|
||||||
void altShiftKeys();
|
void altShiftKeys();
|
||||||
|
|
||||||
std::shared_ptr<ButtonComponent> makeButton(const std::string &key,
|
std::shared_ptr<ButtonComponent> makeButton(const std::string& key,
|
||||||
const std::string &shiftedKey,
|
const std::string& shiftedKey,
|
||||||
const std::string &altedKey,
|
const std::string& altedKey,
|
||||||
const std::string &altshiftedKey);
|
const std::string& altshiftedKey);
|
||||||
|
|
||||||
std::vector<KeyboardButton> mKeyboardButtons;
|
std::vector<KeyboardButton> mKeyboardButtons;
|
||||||
|
|
||||||
|
@ -95,7 +101,7 @@ private:
|
||||||
std::string mClearBtnHelpText;
|
std::string mClearBtnHelpText;
|
||||||
std::string mCancelBtnHelpText;
|
std::string mCancelBtnHelpText;
|
||||||
|
|
||||||
std::function<void(const std::string &)> mOkCallback;
|
std::function<void(const std::string&)> mOkCallback;
|
||||||
|
|
||||||
bool mMultiLine;
|
bool mMultiLine;
|
||||||
bool mComplexMode;
|
bool mComplexMode;
|
||||||
|
|
|
@ -15,25 +15,35 @@
|
||||||
#include "components/MenuComponent.h"
|
#include "components/MenuComponent.h"
|
||||||
#include "guis/GuiMsgBox.h"
|
#include "guis/GuiMsgBox.h"
|
||||||
|
|
||||||
GuiTextEditPopup::GuiTextEditPopup(Window *window,
|
GuiTextEditPopup::GuiTextEditPopup(Window* window,
|
||||||
const HelpStyle &helpstyle,
|
const HelpStyle& helpstyle,
|
||||||
const std::string &title,
|
const std::string& title,
|
||||||
const std::string &initValue,
|
const std::string& initValue,
|
||||||
const std::function<void(const std::string &)> &okCallback,
|
const std::function<void(const std::string&)>& okCallback,
|
||||||
bool multiLine,
|
bool multiLine,
|
||||||
const std::string &acceptBtnText,
|
const std::string& acceptBtnText,
|
||||||
const std::string &saveConfirmationText,
|
const std::string& saveConfirmationText,
|
||||||
const std::string &infoString,
|
const std::string& infoString,
|
||||||
const std::string &defaultValue,
|
const std::string& defaultValue,
|
||||||
const std::string &loadBtnHelpText,
|
const std::string& loadBtnHelpText,
|
||||||
const std::string &clearBtnHelpText,
|
const std::string& clearBtnHelpText,
|
||||||
const std::string &cancelBtnHelpText)
|
const std::string& cancelBtnHelpText)
|
||||||
: GuiComponent{window}, mBackground{window, ":/graphics/frame.svg"},
|
: GuiComponent{window}
|
||||||
mGrid{window, glm::ivec2{1, (infoString != "" && defaultValue != "" ? 5 : 3)}}, mHelpStyle{helpstyle},
|
, mBackground{window, ":/graphics/frame.svg"}
|
||||||
mInitValue{initValue}, mAcceptBtnText{acceptBtnText}, mSaveConfirmationText{saveConfirmationText},
|
, mGrid{window, glm::ivec2{1, (infoString != "" && defaultValue != "" ? 5 : 3)}}
|
||||||
mLoadBtnHelpText{loadBtnHelpText}, mClearBtnHelpText{clearBtnHelpText}, mCancelBtnHelpText{cancelBtnHelpText},
|
, mHelpStyle{helpstyle}
|
||||||
mOkCallback{okCallback}, mMultiLine{multiLine}, mComplexMode{(infoString != "" && defaultValue != "")},
|
, mInitValue{initValue}
|
||||||
mDeleteRepeat{false}, mDeleteRepeatTimer{0} {
|
, mAcceptBtnText{acceptBtnText}
|
||||||
|
, mSaveConfirmationText{saveConfirmationText}
|
||||||
|
, mLoadBtnHelpText{loadBtnHelpText}
|
||||||
|
, mClearBtnHelpText{clearBtnHelpText}
|
||||||
|
, mCancelBtnHelpText{cancelBtnHelpText}
|
||||||
|
, mOkCallback{okCallback}
|
||||||
|
, mMultiLine{multiLine}
|
||||||
|
, mComplexMode{(infoString != "" && defaultValue != "")}
|
||||||
|
, mDeleteRepeat{false}
|
||||||
|
, mDeleteRepeatTimer{0}
|
||||||
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
|
||||||
|
@ -42,9 +52,9 @@ GuiTextEditPopup::GuiTextEditPopup(Window *window,
|
||||||
|
|
||||||
if (mComplexMode) {
|
if (mComplexMode) {
|
||||||
mInfoString = std::make_shared<TextComponent>(
|
mInfoString = std::make_shared<TextComponent>(
|
||||||
mWindow, infoString, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
mWindow, infoString, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
||||||
mDefaultValue = std::make_shared<TextComponent>(
|
mDefaultValue = std::make_shared<TextComponent>(
|
||||||
mWindow, defaultValue, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
mWindow, defaultValue, Font::get(FONT_SIZE_SMALL), 0x555555FF, ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
mText = std::make_shared<TextEditComponent>(mWindow);
|
mText = std::make_shared<TextEditComponent>(mWindow);
|
||||||
|
@ -58,11 +68,11 @@ GuiTextEditPopup::GuiTextEditPopup(Window *window,
|
||||||
}));
|
}));
|
||||||
if (mComplexMode) {
|
if (mComplexMode) {
|
||||||
buttons.push_back(std::make_shared<ButtonComponent>(
|
buttons.push_back(std::make_shared<ButtonComponent>(
|
||||||
mWindow, "load", loadBtnHelpText, [this, defaultValue] {
|
mWindow, "load", loadBtnHelpText, [this, defaultValue] {
|
||||||
mText->setValue(defaultValue);
|
mText->setValue(defaultValue);
|
||||||
mText->setCursor(0);
|
mText->setCursor(0);
|
||||||
mText->setCursor(defaultValue.size());
|
mText->setCursor(defaultValue.size());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "clear", clearBtnHelpText,
|
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "clear", clearBtnHelpText,
|
||||||
|
@ -99,21 +109,22 @@ GuiTextEditPopup::GuiTextEditPopup(Window *window,
|
||||||
|
|
||||||
if (mComplexMode) {
|
if (mComplexMode) {
|
||||||
float infoWidth =
|
float infoWidth =
|
||||||
glm::clamp(0.70f * aspectValue, 0.34f, 0.85f) * Renderer::getScreenWidth();
|
glm::clamp(0.70f * aspectValue, 0.34f, 0.85f) * Renderer::getScreenWidth();
|
||||||
float windowWidth =
|
float windowWidth =
|
||||||
glm::clamp(0.75f * aspectValue, 0.40f, 0.90f) * Renderer::getScreenWidth();
|
glm::clamp(0.75f * aspectValue, 0.40f, 0.90f) * Renderer::getScreenWidth();
|
||||||
|
|
||||||
mDefaultValue->setSize(infoWidth, mDefaultValue->getFont()->getHeight());
|
mDefaultValue->setSize(infoWidth, mDefaultValue->getFont()->getHeight());
|
||||||
|
|
||||||
setSize(windowWidth, mTitle->getFont()->getHeight() + textHeight +
|
setSize(windowWidth, mTitle->getFont()->getHeight() + textHeight +
|
||||||
mButtonGrid->getSize().y + mButtonGrid->getSize().y * 1.85f);
|
mButtonGrid->getSize().y + mButtonGrid->getSize().y * 1.85f);
|
||||||
setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f,
|
setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f,
|
||||||
(Renderer::getScreenHeight() - mSize.y) / 2.0f);
|
(Renderer::getScreenHeight() - mSize.y) / 2.0f);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
float width = glm::clamp(0.54f * aspectValue, 0.20f, 0.70f) * Renderer::getScreenWidth();
|
float width = glm::clamp(0.54f * aspectValue, 0.20f, 0.70f) * Renderer::getScreenWidth();
|
||||||
|
|
||||||
setSize(width, mTitle->getFont()->getHeight() + textHeight + mButtonGrid->getSize().y +
|
setSize(width, mTitle->getFont()->getHeight() + textHeight + mButtonGrid->getSize().y +
|
||||||
mButtonGrid->getSize().y / 2.0f);
|
mButtonGrid->getSize().y / 2.0f);
|
||||||
setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f,
|
setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f,
|
||||||
(Renderer::getScreenHeight() - mSize.y) / 2.0f);
|
(Renderer::getScreenHeight() - mSize.y) / 2.0f);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +135,8 @@ GuiTextEditPopup::GuiTextEditPopup(Window *window,
|
||||||
mText->startEditing();
|
mText->startEditing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditPopup::onSizeChanged() {
|
void GuiTextEditPopup::onSizeChanged()
|
||||||
|
{
|
||||||
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
|
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
|
||||||
mText->setSize(mSize.x - 40.0f * Renderer::getScreenHeightModifier(), mText->getSize().y);
|
mText->setSize(mSize.x - 40.0f * Renderer::getScreenHeightModifier(), mText->getSize().y);
|
||||||
|
|
||||||
|
@ -138,7 +150,8 @@ void GuiTextEditPopup::onSizeChanged() {
|
||||||
mGrid.setSize(mSize);
|
mGrid.setSize(mSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuiTextEditPopup::input(InputConfig *config, Input input) {
|
bool GuiTextEditPopup::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
// Enter key (main key or via numpad) accepts the changes.
|
// Enter key (main key or via numpad) accepts the changes.
|
||||||
if (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() && !mMultiLine &&
|
if (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() && !mMultiLine &&
|
||||||
input.value && (input.id == SDLK_RETURN || input.id == SDLK_KP_ENTER)) {
|
input.value && (input.id == SDLK_RETURN || input.id == SDLK_KP_ENTER)) {
|
||||||
|
@ -146,7 +159,7 @@ bool GuiTextEditPopup::input(InputConfig *config, Input input) {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Dito for the A button if using a controller.
|
// Dito for the A button if using a controller.
|
||||||
else if (config->getDeviceId() != DEVICE_KEYBOARD && mText->isEditing() &&
|
else if (config->getDeviceId() != DEVICE_KEYBOARD && mText->isEditing() &&
|
||||||
config->isMappedTo("a", input) && input.value) {
|
config->isMappedTo("a", input) && input.value) {
|
||||||
this->mOkCallback(mText->getValue());
|
this->mOkCallback(mText->getValue());
|
||||||
|
@ -166,18 +179,19 @@ bool GuiTextEditPopup::input(InputConfig *config, Input input) {
|
||||||
if (mText->getValue() != mInitValue) {
|
if (mText->getValue() != mInitValue) {
|
||||||
// Changes were made, ask if the user wants to save them.
|
// Changes were made, ask if the user wants to save them.
|
||||||
mWindow->pushGui(new GuiMsgBox(
|
mWindow->pushGui(new GuiMsgBox(
|
||||||
mWindow, mHelpStyle, mSaveConfirmationText, "YES",
|
mWindow, mHelpStyle, mSaveConfirmationText, "YES",
|
||||||
[this] {
|
[this] {
|
||||||
this->mOkCallback(mText->getValue());
|
this->mOkCallback(mText->getValue());
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
"NO",
|
"NO",
|
||||||
[this] {
|
[this] {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
delete this;
|
delete this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +216,8 @@ bool GuiTextEditPopup::input(InputConfig *config, Input input) {
|
||||||
|
|
||||||
if (!editing)
|
if (!editing)
|
||||||
mText->stopEditing();
|
mText->stopEditing();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mDeleteRepeat = false;
|
mDeleteRepeat = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -228,12 +243,14 @@ bool GuiTextEditPopup::input(InputConfig *config, Input input) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditPopup::update(int deltaTime) {
|
void GuiTextEditPopup::update(int deltaTime)
|
||||||
|
{
|
||||||
updateDeleteRepeat(deltaTime);
|
updateDeleteRepeat(deltaTime);
|
||||||
GuiComponent::update(deltaTime);
|
GuiComponent::update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HelpPrompt> GuiTextEditPopup::getHelpPrompts() {
|
std::vector<HelpPrompt> GuiTextEditPopup::getHelpPrompts()
|
||||||
|
{
|
||||||
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
|
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
|
||||||
|
|
||||||
if (mText->isEditing())
|
if (mText->isEditing())
|
||||||
|
@ -245,7 +262,8 @@ std::vector<HelpPrompt> GuiTextEditPopup::getHelpPrompts() {
|
||||||
return prompts;
|
return prompts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTextEditPopup::updateDeleteRepeat(int deltaTime) {
|
void GuiTextEditPopup::updateDeleteRepeat(int deltaTime)
|
||||||
|
{
|
||||||
if (!mDeleteRepeat)
|
if (!mDeleteRepeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -15,25 +15,26 @@
|
||||||
#include "components/ComponentGrid.h"
|
#include "components/ComponentGrid.h"
|
||||||
#include "components/TextEditComponent.h"
|
#include "components/TextEditComponent.h"
|
||||||
|
|
||||||
class GuiTextEditPopup : public GuiComponent {
|
class GuiTextEditPopup : public GuiComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
GuiTextEditPopup(Window *window,
|
GuiTextEditPopup(Window* window,
|
||||||
const HelpStyle &helpstyle,
|
const HelpStyle& helpstyle,
|
||||||
const std::string &title,
|
const std::string& title,
|
||||||
const std::string &initValue,
|
const std::string& initValue,
|
||||||
const std::function<void(const std::string &)> &okCallback,
|
const std::function<void(const std::string&)>& okCallback,
|
||||||
bool multiLine,
|
bool multiLine,
|
||||||
const std::string &acceptBtnText = "OK",
|
const std::string& acceptBtnText = "OK",
|
||||||
const std::string &saveConfirmationText = "SAVE CHANGES?",
|
const std::string& saveConfirmationText = "SAVE CHANGES?",
|
||||||
const std::string &infoString = "",
|
const std::string& infoString = "",
|
||||||
const std::string &defaultValue = "",
|
const std::string& defaultValue = "",
|
||||||
const std::string &loadBtnHelpText = "LOAD DEFAULT",
|
const std::string& loadBtnHelpText = "LOAD DEFAULT",
|
||||||
const std::string &clearBtnHelpText = "CLEAR",
|
const std::string& clearBtnHelpText = "CLEAR",
|
||||||
const std::string &cancelBtnHelpText = "DISCARD CHANGES");
|
const std::string& cancelBtnHelpText = "DISCARD CHANGES");
|
||||||
|
|
||||||
void onSizeChanged() override;
|
void onSizeChanged() override;
|
||||||
|
|
||||||
bool input(InputConfig *config, Input input) override;
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ private:
|
||||||
std::string mClearBtnHelpText;
|
std::string mClearBtnHelpText;
|
||||||
std::string mCancelBtnHelpText;
|
std::string mCancelBtnHelpText;
|
||||||
|
|
||||||
std::function<void(const std::string &)> mOkCallback;
|
std::function<void(const std::string&)> mOkCallback;
|
||||||
|
|
||||||
bool mMultiLine;
|
bool mMultiLine;
|
||||||
bool mComplexMode;
|
bool mComplexMode;
|
||||||
|
|
|
@ -562,18 +562,18 @@ float Font::getNewlineStartOffset(const std::string& text,
|
||||||
endChar = static_cast<int>(text.find('\n', charStart));
|
endChar = static_cast<int>(text.find('\n', charStart));
|
||||||
return (xLen - sizeText(text.substr(charStart,
|
return (xLen - sizeText(text.substr(charStart,
|
||||||
static_cast<size_t>(endChar) != std::string::npos ?
|
static_cast<size_t>(endChar) != std::string::npos ?
|
||||||
endChar - charStart :
|
endChar - charStart :
|
||||||
endChar))
|
endChar))
|
||||||
.x) /
|
.x) /
|
||||||
2.0f;
|
2.0f;
|
||||||
}
|
}
|
||||||
case ALIGN_RIGHT: {
|
case ALIGN_RIGHT: {
|
||||||
int endChar = static_cast<int>(text.find('\n', charStart));
|
int endChar = static_cast<int>(text.find('\n', charStart));
|
||||||
return xLen - (sizeText(text.substr(charStart,
|
return xLen - (sizeText(text.substr(charStart,
|
||||||
static_cast<size_t>(endChar) != std::string::npos ?
|
static_cast<size_t>(endChar) != std::string::npos ?
|
||||||
endChar - charStart :
|
endChar - charStart :
|
||||||
endChar))
|
endChar))
|
||||||
.x);
|
.x);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -143,7 +143,7 @@ bool TextureResource::bind()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextureResource> TextureResource::get(const std::string &path,
|
std::shared_ptr<TextureResource> TextureResource::get(const std::string& path,
|
||||||
bool tile,
|
bool tile,
|
||||||
bool forceLoad,
|
bool forceLoad,
|
||||||
bool dynamic,
|
bool dynamic,
|
||||||
|
|
|
@ -25,7 +25,7 @@ class TextureData;
|
||||||
class TextureResource : public IReloadable
|
class TextureResource : public IReloadable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<TextureResource> get(const std::string &path,
|
static std::shared_ptr<TextureResource> get(const std::string& path,
|
||||||
bool tile = false,
|
bool tile = false,
|
||||||
bool forceLoad = false,
|
bool forceLoad = false,
|
||||||
bool dynamic = true,
|
bool dynamic = true,
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
float scaleDuringLoad = 1.0f,
|
float scaleDuringLoad = 1.0f,
|
||||||
bool cacheImage = false);
|
bool cacheImage = false);
|
||||||
|
|
||||||
void initFromPixels(const unsigned char *dataRGBA, size_t width, size_t height);
|
void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height);
|
||||||
virtual void initFromMemory(const char* data, size_t length);
|
virtual void initFromMemory(const char* data, size_t length);
|
||||||
static void manualUnload(std::string path, bool tile);
|
static void manualUnload(std::string path, bool tile);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue