Improved the layout of the scraper GUIs.

Also added the scroll indicators and replaced a text margin hack with a proper solution.
This commit is contained in:
Leon Styhre 2021-10-15 20:58:40 +02:00
parent 050dccb6b8
commit 3683866062
10 changed files with 191 additions and 73 deletions

View file

@ -23,15 +23,13 @@ GuiGameScraper::GuiGameScraper(Window* window,
std::function<void(const ScraperSearchResult&)> doneFunc) std::function<void(const ScraperSearchResult&)> doneFunc)
: GuiComponent(window) : GuiComponent(window)
, mClose(false) , mClose(false)
, mGrid(window, glm::ivec2{1, 7}) , mGrid(window, glm::ivec2{2, 6})
, mBox(window, ":/graphics/frame.svg") , mBox(window, ":/graphics/frame.svg")
, mSearchParams(params) , mSearchParams(params)
{ {
addChild(&mBox); addChild(&mBox);
addChild(&mGrid); addChild(&mGrid);
// Row 0 is a spacer.
std::string scrapeName; std::string scrapeName;
if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) { if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
@ -51,21 +49,37 @@ GuiGameScraper::GuiGameScraper(Window* window,
mWindow, mWindow,
scrapeName + scrapeName +
((mSearchParams.game->getType() == FOLDER) ? " " + ViewController::FOLDER_CHAR : ""), ((mSearchParams.game->getType() == FOLDER) ? " " + ViewController::FOLDER_CHAR : ""),
Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER); Font::get(FONT_SIZE_LARGE), 0x777777FF, ALIGN_CENTER);
mGrid.setEntry(mGameName, glm::ivec2{0, 1}, false, true); mGameName->setColor(0x555555FF);
mGrid.setEntry(mGameName, glm::ivec2{0, 0}, false, true, glm::ivec2{2, 2});
// Row 2 is a spacer.
mSystemName = std::make_shared<TextComponent>( mSystemName = std::make_shared<TextComponent>(
mWindow, Utils::String::toUpper(mSearchParams.system->getFullName()), mWindow, Utils::String::toUpper(mSearchParams.system->getFullName()),
Font::get(FONT_SIZE_SMALL), 0x888888FF, ALIGN_CENTER); Font::get(FONT_SIZE_SMALL), 0x888888FF, ALIGN_CENTER);
mGrid.setEntry(mSystemName, glm::ivec2{0, 3}, false, true); mGrid.setEntry(mSystemName, glm::ivec2{0, 2}, false, true, glm::ivec2{2, 1});
// Row 4 is a spacer. // Row 3 is a spacer.
// GuiScraperSearch. // GuiScraperSearch.
mSearch = std::make_shared<GuiScraperSearch>(window, GuiScraperSearch::NEVER_AUTO_ACCEPT, 1); mSearch = std::make_shared<GuiScraperSearch>(window, GuiScraperSearch::NEVER_AUTO_ACCEPT, 1);
mGrid.setEntry(mSearch, glm::ivec2{0, 5}, true); mGrid.setEntry(mSearch, glm::ivec2{0, 4}, true, true, glm::ivec2{2, 1});
mResultList = mSearch->getResultList();
// Set up scroll indicators.
mScrollUp = std::make_shared<ImageComponent>(mWindow);
mScrollDown = std::make_shared<ImageComponent>(mWindow);
mScrollIndicator =
std::make_shared<ScrollIndicatorComponent>(mResultList, mScrollUp, mScrollDown);
mScrollUp->setResize(0.0f, mGameName->getFont()->getLetterHeight() / 2.0f);
mScrollUp->setOrigin(0.0f, -0.35f);
mScrollDown->setResize(0.0f, mGameName->getFont()->getLetterHeight() / 2.0f);
mScrollDown->setOrigin(0.0f, 0.35f);
mGrid.setEntry(mScrollUp, glm::ivec2{1, 0}, false, false, glm::ivec2{1, 1});
mGrid.setEntry(mScrollDown, glm::ivec2{1, 1}, false, false, glm::ivec2{1, 1});
// Buttons // Buttons
std::vector<std::shared_ptr<ButtonComponent>> buttons; std::vector<std::shared_ptr<ButtonComponent>> buttons;
@ -74,6 +88,9 @@ GuiGameScraper::GuiGameScraper(Window* window,
std::make_shared<ButtonComponent>(mWindow, "REFINE SEARCH", "refine search", [&] { std::make_shared<ButtonComponent>(mWindow, "REFINE SEARCH", "refine search", [&] {
// Refine the search, unless the result has already been accepted. // Refine the search, unless the result has already been accepted.
if (!mSearch->getAcceptedResult()) { if (!mSearch->getAcceptedResult()) {
// Copy any search refine that may have been previously entered by opening
// the input screen using the "Y" button shortcut.
mSearchParams.nameOverride = mSearch->getNameOverride();
mSearch->openInputScreen(mSearchParams); mSearch->openInputScreen(mSearchParams);
mGrid.resetCursor(); mGrid.resetCursor();
} }
@ -92,20 +109,34 @@ GuiGameScraper::GuiGameScraper(Window* window,
})); }));
mButtonGrid = makeButtonGrid(mWindow, buttons); mButtonGrid = makeButtonGrid(mWindow, buttons);
mGrid.setEntry(mButtonGrid, glm::ivec2{0, 6}, true, false); mGrid.setEntry(mButtonGrid, glm::ivec2{0, 5}, true, false, glm::ivec2{2, 1});
mSearch->setAcceptCallback([this, doneFunc](const ScraperSearchResult& result) { mSearch->setAcceptCallback([this, doneFunc](const ScraperSearchResult& result) {
doneFunc(result); doneFunc(result);
close(); close();
}); });
mSearch->setCancelCallback([&] { delete this; }); mSearch->setCancelCallback([&] { delete this; });
mSearch->setRefineCallback([&] {
mScrollUp->setOpacity(0);
mScrollDown->setOpacity(0);
mResultList->resetScrollIndicatorStatus();
});
// Limit the width of the GUI on ultrawide monitors. The 1.778 aspect ratio value is // Limit the width of the GUI on ultrawide monitors. The 1.778 aspect ratio value is
// the 16:9 reference. // the 16:9 reference.
float aspectValue = 1.778f / Renderer::getScreenAspectRatio(); float aspectValue = 1.778f / Renderer::getScreenAspectRatio();
float width = glm::clamp(0.95f * aspectValue, 0.70f, 0.95f) * Renderer::getScreenWidth(); float width = glm::clamp(0.95f * aspectValue, 0.70f, 0.95f) * Renderer::getScreenWidth();
setSize(width, Renderer::getScreenHeight() * 0.747f); float height = (mGameName->getFont()->getLetterHeight() +
static_cast<float>(Renderer::getScreenHeight()) * 0.0637f) +
mSystemName->getFont()->getLetterHeight() +
static_cast<float>(Renderer::getScreenHeight()) * 0.04f +
mButtonGrid->getSize().y + Font::get(FONT_SIZE_MEDIUM)->getHeight() * 8.0f;
// TODO: Temporary hack, see below.
height -= 7.0f * Renderer::getScreenHeightModifier();
setSize(width, height);
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);
@ -115,15 +146,31 @@ GuiGameScraper::GuiGameScraper(Window* window,
void GuiGameScraper::onSizeChanged() void GuiGameScraper::onSizeChanged()
{ {
mGrid.setRowHeightPerc(
0, (mGameName->getFont()->getLetterHeight() + Renderer::getScreenHeight() * 0.0637f) /
mSize.y / 2.0f);
mGrid.setRowHeightPerc(
1, (mGameName->getFont()->getLetterHeight() + Renderer::getScreenHeight() * 0.0637f) /
mSize.y / 2.0f);
mGrid.setRowHeightPerc(2, mSystemName->getFont()->getLetterHeight() / mSize.y, false);
mGrid.setRowHeightPerc(3, 0.04f, false);
mGrid.setRowHeightPerc(4, ((Font::get(FONT_SIZE_MEDIUM)->getHeight() * 8.0f)) / mSize.y, false);
// TODO: Replace this temporary hack with a proper solution. There is some kind of rounding
// issue somewhere that causes a small alignment error. This code partly compensates for this
// at higher resolutions than 1920x1080.
if (Renderer::getScreenHeightModifier() > 1.0f)
mSize.y -= 3.0f * Renderer::getScreenHeightModifier();
mGrid.setColWidthPerc(1, 0.04f);
mGrid.setSize(mSize);
mBox.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f}); mBox.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
mGrid.setRowHeightPerc(0, 0.04f, false); // Add some extra margins to the game name.
mGrid.setRowHeightPerc(1, mGameName->getFont()->getLetterHeight() / mSize.y, false); const float newSizeX = mSize.x * 0.96f;
mGrid.setRowHeightPerc(2, 0.04f, false); mGameName->setSize(newSizeX, mGameName->getSize().y);
mGrid.setRowHeightPerc(3, mSystemName->getFont()->getLetterHeight() / mSize.y, false); mGameName->setPosition((mSize.x - newSizeX) / 2.0f, 0.0f);
mGrid.setRowHeightPerc(4, 0.04f, false);
mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y / mSize.y, false);
mGrid.setSize(mSize);
} }
bool GuiGameScraper::input(InputConfig* config, Input input) bool GuiGameScraper::input(InputConfig* config, Input input)

View file

@ -13,6 +13,7 @@
#include "GuiComponent.h" #include "GuiComponent.h"
#include "components/NinePatchComponent.h" #include "components/NinePatchComponent.h"
#include "components/ScrollIndicatorComponent.h"
#include "guis/GuiScraperSearch.h" #include "guis/GuiScraperSearch.h"
class GuiGameScraper : public GuiComponent class GuiGameScraper : public GuiComponent
@ -38,9 +39,13 @@ private:
NinePatchComponent mBox; NinePatchComponent mBox;
std::shared_ptr<TextComponent> mGameName; std::shared_ptr<TextComponent> mGameName;
std::shared_ptr<ImageComponent> mScrollUp;
std::shared_ptr<ImageComponent> mScrollDown;
std::shared_ptr<ScrollIndicatorComponent> mScrollIndicator;
std::shared_ptr<TextComponent> mSystemName; std::shared_ptr<TextComponent> mSystemName;
std::shared_ptr<GuiScraperSearch> mSearch; std::shared_ptr<GuiScraperSearch> mSearch;
std::shared_ptr<ComponentGrid> mButtonGrid; std::shared_ptr<ComponentGrid> mButtonGrid;
std::shared_ptr<ComponentList> mResultList;
ScraperSearchParams mSearchParams; ScraperSearchParams mSearchParams;

View file

@ -80,8 +80,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
folderPath + Utils::FileSystem::getFileName(scraperParams.game->getPath()) + " [" + folderPath + Utils::FileSystem::getFileName(scraperParams.game->getPath()) + " [" +
Utils::String::toUpper(scraperParams.system->getName()) + "]" + Utils::String::toUpper(scraperParams.system->getName()) + "]" +
(scraperParams.game->getType() == FOLDER ? " " + ViewController::FOLDER_CHAR : ""), (scraperParams.game->getType() == FOLDER ? " " + ViewController::FOLDER_CHAR : ""),
Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER, glm::vec3{}, glm::vec2{}, 0x00000000, Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER);
0.05f);
mGrid.setEntry(mSubtitle, glm::ivec2{0, 2}, false, true, glm::ivec2{2, 1}); mGrid.setEntry(mSubtitle, glm::ivec2{0, 2}, false, true, glm::ivec2{2, 1});
@ -505,6 +504,11 @@ void GuiMetaDataEd::onSizeChanged()
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);
// Add some extra margins to the file/folder name.
const float newSizeX = mSize.x * 0.96f;
mSubtitle->setSize(newSizeX, mSubtitle->getSize().y);
mSubtitle->setPosition((mSize.x - newSizeX) / 2.0f, mSubtitle->getPosition().y);
} }
void GuiMetaDataEd::save() void GuiMetaDataEd::save()

View file

@ -28,7 +28,7 @@ GuiScraperMulti::GuiScraperMulti(Window* window,
bool approveResults) bool approveResults)
: GuiComponent(window) : GuiComponent(window)
, mBackground(window, ":/graphics/frame.svg") , mBackground(window, ":/graphics/frame.svg")
, mGrid(window, glm::ivec2{1, 5}) , mGrid(window, glm::ivec2{2, 6})
, mSearchQueue(searches) , mSearchQueue(searches)
, mApproveResults(approveResults) , mApproveResults(approveResults)
{ {
@ -47,15 +47,15 @@ GuiScraperMulti::GuiScraperMulti(Window* window,
// Set up grid. // Set up grid.
mTitle = std::make_shared<TextComponent>(mWindow, "SCRAPING IN PROGRESS", mTitle = std::make_shared<TextComponent>(mWindow, "SCRAPING IN PROGRESS",
Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER); Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER);
mGrid.setEntry(mTitle, glm::ivec2{0, 0}, false, true); mGrid.setEntry(mTitle, glm::ivec2{0, 0}, false, true, glm::ivec2{2, 2});
mSystem = std::make_shared<TextComponent>(mWindow, "SYSTEM", Font::get(FONT_SIZE_MEDIUM), mSystem = std::make_shared<TextComponent>(mWindow, "SYSTEM", Font::get(FONT_SIZE_MEDIUM),
0x777777FF, ALIGN_CENTER); 0x777777FF, ALIGN_CENTER);
mGrid.setEntry(mSystem, glm::ivec2{0, 1}, false, true); mGrid.setEntry(mSystem, glm::ivec2{0, 2}, false, true, glm::ivec2{2, 1});
mSubtitle = std::make_shared<TextComponent>( mSubtitle = std::make_shared<TextComponent>(
mWindow, "subtitle text", Font::get(FONT_SIZE_SMALL), 0x888888FF, ALIGN_CENTER); mWindow, "subtitle text", Font::get(FONT_SIZE_SMALL), 0x888888FF, ALIGN_CENTER);
mGrid.setEntry(mSubtitle, glm::ivec2{0, 2}, false, true); mGrid.setEntry(mSubtitle, glm::ivec2{0, 3}, false, true, glm::ivec2{2, 1});
if (mApproveResults && !Settings::getInstance()->getBool("ScraperSemiautomatic")) if (mApproveResults && !Settings::getInstance()->getBool("ScraperSemiautomatic"))
mSearchComp = std::make_shared<GuiScraperSearch>( mSearchComp = std::make_shared<GuiScraperSearch>(
@ -70,10 +70,34 @@ GuiScraperMulti::GuiScraperMulti(Window* window,
std::bind(&GuiScraperMulti::acceptResult, this, std::placeholders::_1)); std::bind(&GuiScraperMulti::acceptResult, this, std::placeholders::_1));
mSearchComp->setSkipCallback(std::bind(&GuiScraperMulti::skip, this)); mSearchComp->setSkipCallback(std::bind(&GuiScraperMulti::skip, this));
mSearchComp->setCancelCallback(std::bind(&GuiScraperMulti::finish, this)); mSearchComp->setCancelCallback(std::bind(&GuiScraperMulti::finish, this));
mGrid.setEntry(mSearchComp, glm::ivec2{0, 3}, mSearchComp->setRefineCallback([&] {
mSearchComp->getSearchType() != GuiScraperSearch::ALWAYS_ACCEPT_FIRST_RESULT, mScrollUp->setOpacity(0);
true); mScrollDown->setOpacity(0);
mResultList->resetScrollIndicatorStatus();
});
mGrid.setEntry(mSearchComp, glm::ivec2{0, 4},
mSearchComp->getSearchType() != GuiScraperSearch::ALWAYS_ACCEPT_FIRST_RESULT,
true, glm::ivec2{2, 1});
mResultList = mSearchComp->getResultList();
// Set up scroll indicators.
mScrollUp = std::make_shared<ImageComponent>(mWindow);
mScrollDown = std::make_shared<ImageComponent>(mWindow);
mScrollIndicator =
std::make_shared<ScrollIndicatorComponent>(mResultList, mScrollUp, mScrollDown);
mScrollUp->setResize(0.0f, mTitle->getFont()->getLetterHeight() / 2.0f);
mScrollUp->setOrigin(0.0f, -0.35f);
mScrollDown->setResize(0.0f, mTitle->getFont()->getLetterHeight() / 2.0f);
mScrollDown->setOrigin(0.0f, 0.35f);
mGrid.setEntry(mScrollUp, glm::ivec2{1, 0}, false, false, glm::ivec2{1, 1});
mGrid.setEntry(mScrollDown, glm::ivec2{1, 1}, false, false, glm::ivec2{1, 1});
// Buttons.
std::vector<std::shared_ptr<ButtonComponent>> buttons; std::vector<std::shared_ptr<ButtonComponent>> buttons;
if (mApproveResults) { if (mApproveResults) {
@ -125,14 +149,23 @@ GuiScraperMulti::GuiScraperMulti(Window* window,
std::bind(&GuiScraperMulti::finish, this))); std::bind(&GuiScraperMulti::finish, this)));
mButtonGrid = makeButtonGrid(mWindow, buttons); mButtonGrid = makeButtonGrid(mWindow, buttons);
mGrid.setEntry(mButtonGrid, glm::ivec2{0, 4}, true, false); mGrid.setEntry(mButtonGrid, glm::ivec2{0, 5}, true, false, glm::ivec2{2, 1});
// Limit the width of the GUI on ultrawide monitors. The 1.778 aspect ratio value is // Limit the width of the GUI on ultrawide monitors. The 1.778 aspect ratio value is
// the 16:9 reference. // the 16:9 reference.
float aspectValue = 1.778f / Renderer::getScreenAspectRatio(); float aspectValue = 1.778f / Renderer::getScreenAspectRatio();
float width = glm::clamp(0.95f * aspectValue, 0.70f, 0.95f) * Renderer::getScreenWidth(); float width = glm::clamp(0.95f * aspectValue, 0.70f, 0.95f) * Renderer::getScreenWidth();
setSize(width, Renderer::getScreenHeight() * 0.849f); float height = (mTitle->getFont()->getLetterHeight() +
static_cast<float>(Renderer::getScreenHeight()) * 0.0637f) +
mSystem->getFont()->getLetterHeight() +
mSubtitle->getFont()->getHeight() * 1.75f + mButtonGrid->getSize().y +
Font::get(FONT_SIZE_MEDIUM)->getHeight() * 7.0f;
// TODO: Temporary hack, see below.
height -= 7.0f * Renderer::getScreenHeightModifier();
setSize(width, height);
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);
@ -153,13 +186,26 @@ GuiScraperMulti::~GuiScraperMulti()
void GuiScraperMulti::onSizeChanged() void GuiScraperMulti::onSizeChanged()
{ {
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f}); mGrid.setRowHeightPerc(
0, (mTitle->getFont()->getLetterHeight() + Renderer::getScreenHeight() * 0.0637f) /
mSize.y / 2.0f);
mGrid.setRowHeightPerc(
1, (mTitle->getFont()->getLetterHeight() + Renderer::getScreenHeight() * 0.0637f) /
mSize.y / 2.0f);
mGrid.setRowHeightPerc(2, (mSystem->getFont()->getLetterHeight()) / mSize.y, false);
mGrid.setRowHeightPerc(3, mSubtitle->getFont()->getHeight() * 1.75f / mSize.y, false);
mGrid.setRowHeightPerc(4, ((Font::get(FONT_SIZE_MEDIUM)->getHeight() * 7.0f)) / mSize.y, false);
// TODO: Replace this temporary hack with a proper solution. There is some kind of rounding
// issue somewhere that causes a small alignment error. This code partly compensates for this
// at higher resolutions than 1920x1080.
if (Renderer::getScreenHeightModifier() > 1.0f)
mSize.y -= 3.0f * Renderer::getScreenHeightModifier();
mGrid.setColWidthPerc(1, 0.04f);
mGrid.setRowHeightPerc(0, mTitle->getFont()->getLetterHeight() * 1.9725f / mSize.y, false);
mGrid.setRowHeightPerc(1, (mSystem->getFont()->getLetterHeight() + 2.0f) / mSize.y, false);
mGrid.setRowHeightPerc(2, mSubtitle->getFont()->getHeight() * 1.75f / mSize.y, false);
mGrid.setRowHeightPerc(4, mButtonGrid->getSize().y / mSize.y, false);
mGrid.setSize(mSize); mGrid.setSize(mSize);
mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f});
} }
void GuiScraperMulti::doNextSearch() void GuiScraperMulti::doNextSearch()
@ -189,6 +235,10 @@ void GuiScraperMulti::doNextSearch()
scrapeName = Utils::FileSystem::getFileName(mSearchQueue.front().game->getPath()); scrapeName = Utils::FileSystem::getFileName(mSearchQueue.front().game->getPath());
} }
mScrollUp->setOpacity(0);
mScrollDown->setOpacity(0);
mResultList->resetScrollIndicatorStatus();
// Extract possible subfolders from the path. // Extract possible subfolders from the path.
std::string folderPath = std::string folderPath =
Utils::String::replace(Utils::FileSystem::getParent(mSearchQueue.front().game->getPath()), Utils::String::replace(Utils::FileSystem::getParent(mSearchQueue.front().game->getPath()),
@ -264,9 +314,6 @@ void GuiScraperMulti::finish()
std::vector<HelpPrompt> GuiScraperMulti::getHelpPrompts() std::vector<HelpPrompt> GuiScraperMulti::getHelpPrompts()
{ {
std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts(); std::vector<HelpPrompt> prompts = mGrid.getHelpPrompts();
// Remove the 'Choose' entry if in fully automatic mode.
if (!mApproveResults)
prompts.pop_back();
return prompts; return prompts;
} }

View file

@ -16,6 +16,7 @@
#include "MetaData.h" #include "MetaData.h"
#include "components/ComponentGrid.h" #include "components/ComponentGrid.h"
#include "components/NinePatchComponent.h" #include "components/NinePatchComponent.h"
#include "components/ScrollIndicatorComponent.h"
#include "scrapers/Scraper.h" #include "scrapers/Scraper.h"
class GuiScraperSearch; class GuiScraperSearch;
@ -45,10 +46,14 @@ private:
ComponentGrid mGrid; ComponentGrid mGrid;
std::shared_ptr<TextComponent> mTitle; std::shared_ptr<TextComponent> mTitle;
std::shared_ptr<ImageComponent> mScrollUp;
std::shared_ptr<ImageComponent> mScrollDown;
std::shared_ptr<ScrollIndicatorComponent> mScrollIndicator;
std::shared_ptr<TextComponent> mSystem; std::shared_ptr<TextComponent> mSystem;
std::shared_ptr<TextComponent> mSubtitle; std::shared_ptr<TextComponent> mSubtitle;
std::shared_ptr<GuiScraperSearch> mSearchComp; std::shared_ptr<GuiScraperSearch> mSearchComp;
std::shared_ptr<ComponentGrid> mButtonGrid; std::shared_ptr<ComponentGrid> mButtonGrid;
std::shared_ptr<ComponentList> mResultList;
std::queue<ScraperSearchParams> mSearchQueue; std::queue<ScraperSearchParams> mSearchQueue;
std::vector<MetaDataDecl> mMetaDataDecl; std::vector<MetaDataDecl> mMetaDataDecl;

View file

@ -39,7 +39,7 @@
GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int scrapeCount) GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int scrapeCount)
: GuiComponent(window) : GuiComponent(window)
, mGrid(window, glm::ivec2{4, 3}) , mGrid(window, glm::ivec2{5, 3})
, mSearchType(type) , mSearchType(type)
, mScrapeCount(scrapeCount) , mScrapeCount(scrapeCount)
, mRefinedSearch(false) , mRefinedSearch(false)
@ -88,14 +88,11 @@ GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int
mMD_ReleaseDate = std::make_shared<DateTimeEditComponent>(mWindow); mMD_ReleaseDate = std::make_shared<DateTimeEditComponent>(mWindow);
mMD_ReleaseDate->setColor(mdColor); mMD_ReleaseDate->setColor(mdColor);
mMD_ReleaseDate->setUppercase(true); mMD_ReleaseDate->setUppercase(true);
mMD_Developer = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT, mMD_Developer = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT);
glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f); mMD_Publisher = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT);
mMD_Publisher = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT, mMD_Genre =
glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f); std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT, glm::vec3{});
mMD_Genre = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT, glm::vec3{}, mMD_Players = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT);
glm::vec2{}, 0x00000000, 0.02f);
mMD_Players = std::make_shared<TextComponent>(mWindow, "", font, mdColor, ALIGN_LEFT,
glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f);
mMD_Filler = std::make_shared<TextComponent>(mWindow, "", font, mdColor); mMD_Filler = std::make_shared<TextComponent>(mWindow, "", font, mdColor);
if (Settings::getInstance()->getString("Scraper") != "thegamesdb") if (Settings::getInstance()->getString("Scraper") != "thegamesdb")
@ -193,45 +190,47 @@ void GuiScraperSearch::onSizeChanged()
mGrid.setColWidthPerc(1, 0.25f); mGrid.setColWidthPerc(1, 0.25f);
if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT)
mGrid.setColWidthPerc(2, 0.25f); mGrid.setColWidthPerc(2, 0.33f);
else else
mGrid.setColWidthPerc(2, 0.28f); mGrid.setColWidthPerc(2, 0.30f);
// Row heights. // Row heights.
if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) // Show name. if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) // Show name.
mGrid.setRowHeightPerc(0, (mResultName->getFont()->getHeight() * 1.6f) / mGrid.setRowHeightPerc(0, (mResultName->getFont()->getHeight() * 1.6f) /
mGrid.getSize().y); // Result name. mGrid.getSize().y); // Result name.
else else
mGrid.setRowHeightPerc(0, 0.0825f); // Hide name but do padding. mGrid.setRowHeightPerc(0, 0.0725f); // Hide name but do padding.
if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT)
mGrid.setRowHeightPerc(2, 0.2f); mGrid.setRowHeightPerc(2, 0.2f);
else else
mGrid.setRowHeightPerc(1, 0.505f); mGrid.setRowHeightPerc(1, 0.505f);
const float boxartCellScale = 0.9f; const float thumbnailCellScale = 0.93f;
// Limit thumbnail size using setMaxHeight - we do this instead of letting mGrid // Limit thumbnail size using setMaxHeight - we do this instead of letting mGrid
// call setSize because it maintains the aspect ratio. // call setSize because it maintains the aspect ratio.
// We also pad a little so it doesn't rub up against the metadata labels. // We also pad a little so it doesn't rub up against the metadata labels.
mResultThumbnail->setMaxSize(mGrid.getColWidth(1) * boxartCellScale, mGrid.getRowHeight(1)); mResultThumbnail->setMaxSize(mGrid.getColWidth(1) * thumbnailCellScale, mGrid.getRowHeight(1));
// Metadata. // Metadata.
resizeMetadata(); resizeMetadata();
// Small vertical spacer between the metadata fields and the result list.
mGrid.setColWidthPerc(3, 0.004f);
if (mSearchType != ALWAYS_ACCEPT_FIRST_RESULT) if (mSearchType != ALWAYS_ACCEPT_FIRST_RESULT)
mDescContainer->setSize(mGrid.getColWidth(1) * boxartCellScale + mGrid.getColWidth(2), mDescContainer->setSize(mGrid.getColWidth(1) * thumbnailCellScale + mGrid.getColWidth(2),
mResultDesc->getFont()->getHeight() * 3.0f); mResultDesc->getFont()->getHeight() * 3.0f);
else else
mDescContainer->setSize(mGrid.getColWidth(3) * boxartCellScale, mDescContainer->setSize(mGrid.getColWidth(4) * thumbnailCellScale,
mResultDesc->getFont()->getHeight() * 6.0f); mResultDesc->getFont()->getHeight() * 6.0f);
// Make description text wrap at edge of container. // Make description text wrap at edge of container.
mResultDesc->setSize(mDescContainer->getSize().x, 0.0f); mResultDesc->setSize(mDescContainer->getSize().x, 0.0f);
// Set the width of mResultName to the cell width so that text abbreviation will work correctly. // Set the width of mResultName to the cell width so that text abbreviation will work correctly.
glm::vec2 resultNameSize{mResultName->getSize()}; mResultName->setSize(mGrid.getColWidth(1) + mGrid.getColWidth(2), mResultName->getSize().y);
mResultName->setSize(mGrid.getColWidth(3), resultNameSize.y);
mGrid.onSizeChanged(); mGrid.onSizeChanged();
mBusyAnim.setSize(mSize); mBusyAnim.setSize(mSize);
@ -289,30 +288,30 @@ void GuiScraperSearch::updateViewStyle()
// Add them back depending on search type. // Add them back depending on search type.
if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) { if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) {
// Show name. // Show name.
mGrid.setEntry(mResultName, glm::ivec2{1, 0}, false, false, glm::ivec2{2, 1}, mGrid.setEntry(mResultName, glm::ivec2{1, 0}, false, false, glm::ivec2{3, 1},
GridFlags::BORDER_TOP); GridFlags::BORDER_TOP);
// Need a border on the bottom left. // Need a border on the bottom left.
mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), glm::ivec2{0, 2}, false, false, mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), glm::ivec2{0, 2}, false, false,
glm::ivec2{3, 1}, GridFlags::BORDER_BOTTOM); glm::ivec2{4, 1}, GridFlags::BORDER_BOTTOM);
// Show description on the right. // Show description on the right.
mGrid.setEntry(mDescContainer, glm::ivec2{3, 0}, false, false, glm::ivec2{1, 3}, mGrid.setEntry(mDescContainer, glm::ivec2{4, 0}, false, false, glm::ivec2{1, 3},
GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM); GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM | GridFlags::BORDER_LEFT);
// Make description text wrap at edge of container. // Make description text wrap at edge of container.
mResultDesc->setSize(mDescContainer->getSize().x, 0.0f); mResultDesc->setSize(mDescContainer->getSize().x, 0.0f);
} }
else { else {
// Fake row where name would be. // Fake row where name would be.
mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), glm::ivec2{1, 0}, false, true, mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), glm::ivec2{1, 0}, false, true,
glm::ivec2{2, 1}, GridFlags::BORDER_TOP); glm::ivec2{3, 1}, GridFlags::BORDER_TOP);
// Show result list on the right. // Show result list on the right.
mGrid.setEntry(mResultList, glm::ivec2{3, 0}, true, true, glm::ivec2{1, 3}, mGrid.setEntry(mResultList, glm::ivec2{4, 0}, true, true, glm::ivec2{1, 3},
GridFlags::BORDER_LEFT | GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM); GridFlags::BORDER_LEFT | GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM);
// Show description under image/info. // Show description under image/info.
mGrid.setEntry(mDescContainer, glm::ivec2{1, 2}, false, false, glm::ivec2{2, 1}, mGrid.setEntry(mDescContainer, glm::ivec2{1, 2}, false, false, glm::ivec2{3, 1},
GridFlags::BORDER_BOTTOM); GridFlags::BORDER_BOTTOM);
// Make description text wrap at edge of container. // Make description text wrap at edge of container.
mResultDesc->setSize(mDescContainer->getSize().x, 0); mResultDesc->setSize(mDescContainer->getSize().x, 0);
@ -798,6 +797,8 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params)
stop(); stop();
mRefinedSearch = true; mRefinedSearch = true;
params.nameOverride = name; params.nameOverride = name;
if (mRefineCallback != nullptr)
mRefineCallback();
search(params); search(params);
}; };

View file

@ -71,6 +71,10 @@ public:
{ {
mCancelCallback = cancelCallback; mCancelCallback = cancelCallback;
} }
void setRefineCallback(const std::function<void()>& refineCallback)
{
mRefineCallback = refineCallback;
}
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override; void update(int deltaTime) override;
@ -92,6 +96,8 @@ public:
void onFocusGained() override { mGrid.onFocusGained(); } void onFocusGained() override { mGrid.onFocusGained(); }
void onFocusLost() override { mGrid.onFocusLost(); } void onFocusLost() override { mGrid.onFocusLost(); }
std::shared_ptr<ComponentList>& getResultList() { return mResultList; }
private: private:
void updateViewStyle(); void updateViewStyle();
void updateThumbnail(); void updateThumbnail();
@ -152,6 +158,7 @@ private:
std::function<void(const ScraperSearchResult&)> mAcceptCallback; std::function<void(const ScraperSearchResult&)> mAcceptCallback;
std::function<void()> mSkipCallback; std::function<void()> mSkipCallback;
std::function<void()> mCancelCallback; std::function<void()> mCancelCallback;
std::function<void()> mRefineCallback;
unsigned int mScrapeCount; unsigned int mScrapeCount;
bool mRefinedSearch; bool mRefinedSearch;
bool mBlockAccept; bool mBlockAccept;

View file

@ -86,6 +86,13 @@ public:
float getTotalRowHeight() const; float getTotalRowHeight() const;
float getRowHeight(int row) const { return getRowHeight(mEntries.at(row).data); } float getRowHeight(int row) const { return getRowHeight(mEntries.at(row).data); }
void resetScrollIndicatorStatus()
{
mScrollIndicatorStatus = SCROLL_NONE;
if (mScrollIndicatorChangedCallback != nullptr)
mScrollIndicatorChangedCallback(mScrollIndicatorStatus);
}
void setCursorChangedCallback(const std::function<void(CursorState state)>& callback) void setCursorChangedCallback(const std::function<void(CursorState state)>& callback)
{ {
mCursorChangedCallback = callback; mCursorChangedCallback = callback;

View file

@ -17,7 +17,6 @@ TextComponent::TextComponent(Window* window)
, mFont{Font::get(FONT_SIZE_MEDIUM)} , mFont{Font::get(FONT_SIZE_MEDIUM)}
, mColor{0x000000FF} , mColor{0x000000FF}
, mBgColor{0} , mBgColor{0}
, mMargin{0.0f}
, mRenderBackground{false} , mRenderBackground{false}
, mUppercase{false} , mUppercase{false}
, mAutoCalcExtent{1, 1} , mAutoCalcExtent{1, 1}
@ -36,13 +35,11 @@ TextComponent::TextComponent(Window* window,
Alignment align, Alignment align,
glm::vec3 pos, glm::vec3 pos,
glm::vec2 size, glm::vec2 size,
unsigned int bgcolor, unsigned int bgcolor)
float margin)
: GuiComponent{window} : GuiComponent{window}
, mFont{nullptr} , mFont{nullptr}
, mColor{0x000000FF} , mColor{0x000000FF}
, mBgColor{0} , mBgColor{0}
, mMargin{margin}
, mRenderBackground{false} , mRenderBackground{false}
, mUppercase{false} , mUppercase{false}
, mAutoCalcExtent{1, 1} , mAutoCalcExtent{1, 1}
@ -238,12 +235,12 @@ void TextComponent::onTextChanged()
// Abbreviate text. // Abbreviate text.
const std::string abbrev = "..."; const std::string abbrev = "...";
glm::vec2 abbrevSize{f->sizeText(abbrev)}; glm::vec2 abbrevSize{f->sizeText(abbrev)};
// mMargin adds a margin around the text if it's abbreviated.
float marginAdjustedSize = mSize.x - (mSize.x * mMargin);
while (text.size() && size.x + abbrevSize.x > marginAdjustedSize) { while (text.size() && size.x + abbrevSize.x > mSize.x) {
size_t newSize = Utils::String::prevCursor(text, text.size()); size_t newSize = Utils::String::prevCursor(text, text.size());
text.erase(newSize, text.size() - newSize); text.erase(newSize, text.size() - newSize);
if (!text.empty() && text.back() == ' ')
text.pop_back();
size = f->sizeText(text); size = f->sizeText(text);
} }

View file

@ -32,8 +32,7 @@ public:
Alignment align = ALIGN_LEFT, Alignment align = ALIGN_LEFT,
glm::vec3 pos = {}, glm::vec3 pos = {},
glm::vec2 size = {}, glm::vec2 size = {},
unsigned int bgcolor = 0x00000000, unsigned int bgcolor = 0x00000000);
float margin = 0.0f);
void setFont(const std::shared_ptr<Font>& font); void setFont(const std::shared_ptr<Font>& font);
void setUppercase(bool uppercase); void setUppercase(bool uppercase);
@ -89,7 +88,6 @@ private:
unsigned int mBgColor; unsigned int mBgColor;
unsigned char mColorOpacity; unsigned char mColorOpacity;
unsigned char mBgColorOpacity; unsigned char mBgColorOpacity;
float mMargin;
bool mRenderBackground; bool mRenderBackground;
bool mUppercase; bool mUppercase;