diff --git a/es-app/src/guis/GuiGameScraper.cpp b/es-app/src/guis/GuiGameScraper.cpp index 9ddc85caa..bcda1e93f 100644 --- a/es-app/src/guis/GuiGameScraper.cpp +++ b/es-app/src/guis/GuiGameScraper.cpp @@ -23,15 +23,13 @@ GuiGameScraper::GuiGameScraper(Window* window, std::function doneFunc) : GuiComponent(window) , mClose(false) - , mGrid(window, glm::ivec2{1, 7}) + , mGrid(window, glm::ivec2{2, 6}) , mBox(window, ":/graphics/frame.svg") , mSearchParams(params) { addChild(&mBox); addChild(&mGrid); - // Row 0 is a spacer. - std::string scrapeName; if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) { @@ -51,21 +49,37 @@ GuiGameScraper::GuiGameScraper(Window* window, mWindow, scrapeName + ((mSearchParams.game->getType() == FOLDER) ? " " + ViewController::FOLDER_CHAR : ""), - Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER); - mGrid.setEntry(mGameName, glm::ivec2{0, 1}, false, true); - - // Row 2 is a spacer. + Font::get(FONT_SIZE_LARGE), 0x777777FF, ALIGN_CENTER); + mGameName->setColor(0x555555FF); + mGrid.setEntry(mGameName, glm::ivec2{0, 0}, false, true, glm::ivec2{2, 2}); mSystemName = std::make_shared( mWindow, Utils::String::toUpper(mSearchParams.system->getFullName()), 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. mSearch = std::make_shared(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(mWindow); + mScrollDown = std::make_shared(mWindow); + mScrollIndicator = + std::make_shared(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 std::vector> buttons; @@ -74,6 +88,9 @@ GuiGameScraper::GuiGameScraper(Window* window, std::make_shared(mWindow, "REFINE SEARCH", "refine search", [&] { // Refine the search, unless the result has already been accepted. 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); mGrid.resetCursor(); } @@ -92,20 +109,34 @@ GuiGameScraper::GuiGameScraper(Window* window, })); 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) { doneFunc(result); close(); }); 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 // the 16:9 reference. float aspectValue = 1.778f / Renderer::getScreenAspectRatio(); 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(Renderer::getScreenHeight()) * 0.0637f) + + mSystemName->getFont()->getLetterHeight() + + static_cast(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, (Renderer::getScreenHeight() - mSize.y) / 2.0f); @@ -115,15 +146,31 @@ GuiGameScraper::GuiGameScraper(Window* window, 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}); - mGrid.setRowHeightPerc(0, 0.04f, false); - mGrid.setRowHeightPerc(1, mGameName->getFont()->getLetterHeight() / mSize.y, false); - mGrid.setRowHeightPerc(2, 0.04f, false); - mGrid.setRowHeightPerc(3, mSystemName->getFont()->getLetterHeight() / mSize.y, false); - mGrid.setRowHeightPerc(4, 0.04f, false); - mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y / mSize.y, false); - mGrid.setSize(mSize); + // Add some extra margins to the game name. + const float newSizeX = mSize.x * 0.96f; + mGameName->setSize(newSizeX, mGameName->getSize().y); + mGameName->setPosition((mSize.x - newSizeX) / 2.0f, 0.0f); } bool GuiGameScraper::input(InputConfig* config, Input input) diff --git a/es-app/src/guis/GuiGameScraper.h b/es-app/src/guis/GuiGameScraper.h index b910c1351..040f1e072 100644 --- a/es-app/src/guis/GuiGameScraper.h +++ b/es-app/src/guis/GuiGameScraper.h @@ -13,6 +13,7 @@ #include "GuiComponent.h" #include "components/NinePatchComponent.h" +#include "components/ScrollIndicatorComponent.h" #include "guis/GuiScraperSearch.h" class GuiGameScraper : public GuiComponent @@ -38,9 +39,13 @@ private: NinePatchComponent mBox; std::shared_ptr mGameName; + std::shared_ptr mScrollUp; + std::shared_ptr mScrollDown; + std::shared_ptr mScrollIndicator; std::shared_ptr mSystemName; std::shared_ptr mSearch; std::shared_ptr mButtonGrid; + std::shared_ptr mResultList; ScraperSearchParams mSearchParams; diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 594b55fe6..5a945c640 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -80,8 +80,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, folderPath + Utils::FileSystem::getFileName(scraperParams.game->getPath()) + " [" + Utils::String::toUpper(scraperParams.system->getName()) + "]" + (scraperParams.game->getType() == FOLDER ? " " + ViewController::FOLDER_CHAR : ""), - Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER, glm::vec3{}, glm::vec2{}, 0x00000000, - 0.05f); + Font::get(FONT_SIZE_SMALL), 0x777777FF, ALIGN_CENTER); 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, (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() diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index 067352199..50b8aab67 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -28,7 +28,7 @@ GuiScraperMulti::GuiScraperMulti(Window* window, bool approveResults) : GuiComponent(window) , mBackground(window, ":/graphics/frame.svg") - , mGrid(window, glm::ivec2{1, 5}) + , mGrid(window, glm::ivec2{2, 6}) , mSearchQueue(searches) , mApproveResults(approveResults) { @@ -47,15 +47,15 @@ GuiScraperMulti::GuiScraperMulti(Window* window, // Set up grid. mTitle = std::make_shared(mWindow, "SCRAPING IN PROGRESS", 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(mWindow, "SYSTEM", Font::get(FONT_SIZE_MEDIUM), 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( 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")) mSearchComp = std::make_shared( @@ -70,10 +70,34 @@ GuiScraperMulti::GuiScraperMulti(Window* window, std::bind(&GuiScraperMulti::acceptResult, this, std::placeholders::_1)); mSearchComp->setSkipCallback(std::bind(&GuiScraperMulti::skip, this)); mSearchComp->setCancelCallback(std::bind(&GuiScraperMulti::finish, this)); - mGrid.setEntry(mSearchComp, glm::ivec2{0, 3}, - mSearchComp->getSearchType() != GuiScraperSearch::ALWAYS_ACCEPT_FIRST_RESULT, - true); + mSearchComp->setRefineCallback([&] { + mScrollUp->setOpacity(0); + 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(mWindow); + mScrollDown = std::make_shared(mWindow); + mScrollIndicator = + std::make_shared(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> buttons; if (mApproveResults) { @@ -125,14 +149,23 @@ GuiScraperMulti::GuiScraperMulti(Window* window, std::bind(&GuiScraperMulti::finish, this))); 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 // the 16:9 reference. float aspectValue = 1.778f / Renderer::getScreenAspectRatio(); 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(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, (Renderer::getScreenHeight() - mSize.y) / 2.0f); @@ -153,13 +186,26 @@ GuiScraperMulti::~GuiScraperMulti() 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); + mBackground.fitTo(mSize, glm::vec3{}, glm::vec2{-32.0f, -32.0f}); } void GuiScraperMulti::doNextSearch() @@ -189,6 +235,10 @@ void GuiScraperMulti::doNextSearch() scrapeName = Utils::FileSystem::getFileName(mSearchQueue.front().game->getPath()); } + mScrollUp->setOpacity(0); + mScrollDown->setOpacity(0); + mResultList->resetScrollIndicatorStatus(); + // Extract possible subfolders from the path. std::string folderPath = Utils::String::replace(Utils::FileSystem::getParent(mSearchQueue.front().game->getPath()), @@ -264,9 +314,6 @@ void GuiScraperMulti::finish() std::vector GuiScraperMulti::getHelpPrompts() { std::vector prompts = mGrid.getHelpPrompts(); - // Remove the 'Choose' entry if in fully automatic mode. - if (!mApproveResults) - prompts.pop_back(); return prompts; } diff --git a/es-app/src/guis/GuiScraperMulti.h b/es-app/src/guis/GuiScraperMulti.h index 63c755f6b..d71525086 100644 --- a/es-app/src/guis/GuiScraperMulti.h +++ b/es-app/src/guis/GuiScraperMulti.h @@ -16,6 +16,7 @@ #include "MetaData.h" #include "components/ComponentGrid.h" #include "components/NinePatchComponent.h" +#include "components/ScrollIndicatorComponent.h" #include "scrapers/Scraper.h" class GuiScraperSearch; @@ -45,10 +46,14 @@ private: ComponentGrid mGrid; std::shared_ptr mTitle; + std::shared_ptr mScrollUp; + std::shared_ptr mScrollDown; + std::shared_ptr mScrollIndicator; std::shared_ptr mSystem; std::shared_ptr mSubtitle; std::shared_ptr mSearchComp; std::shared_ptr mButtonGrid; + std::shared_ptr mResultList; std::queue mSearchQueue; std::vector mMetaDataDecl; diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 340eb81e2..6a8709c35 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -39,7 +39,7 @@ GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int scrapeCount) : GuiComponent(window) - , mGrid(window, glm::ivec2{4, 3}) + , mGrid(window, glm::ivec2{5, 3}) , mSearchType(type) , mScrapeCount(scrapeCount) , mRefinedSearch(false) @@ -88,14 +88,11 @@ GuiScraperSearch::GuiScraperSearch(Window* window, SearchType type, unsigned int mMD_ReleaseDate = std::make_shared(mWindow); mMD_ReleaseDate->setColor(mdColor); mMD_ReleaseDate->setUppercase(true); - mMD_Developer = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT, - glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f); - mMD_Publisher = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT, - glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f); - mMD_Genre = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT, glm::vec3{}, - glm::vec2{}, 0x00000000, 0.02f); - mMD_Players = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT, - glm::vec3{}, glm::vec2{}, 0x00000000, 0.02f); + mMD_Developer = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT); + mMD_Publisher = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT); + mMD_Genre = + std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT, glm::vec3{}); + mMD_Players = std::make_shared(mWindow, "", font, mdColor, ALIGN_LEFT); mMD_Filler = std::make_shared(mWindow, "", font, mdColor); if (Settings::getInstance()->getString("Scraper") != "thegamesdb") @@ -193,45 +190,47 @@ void GuiScraperSearch::onSizeChanged() mGrid.setColWidthPerc(1, 0.25f); if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) - mGrid.setColWidthPerc(2, 0.25f); + mGrid.setColWidthPerc(2, 0.33f); else - mGrid.setColWidthPerc(2, 0.28f); + mGrid.setColWidthPerc(2, 0.30f); // Row heights. if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) // Show name. mGrid.setRowHeightPerc(0, (mResultName->getFont()->getHeight() * 1.6f) / mGrid.getSize().y); // Result name. 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) mGrid.setRowHeightPerc(2, 0.2f); else 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 // call setSize because it maintains the aspect ratio. // 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. resizeMetadata(); + // Small vertical spacer between the metadata fields and the result list. + mGrid.setColWidthPerc(3, 0.004f); + 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); else - mDescContainer->setSize(mGrid.getColWidth(3) * boxartCellScale, + mDescContainer->setSize(mGrid.getColWidth(4) * thumbnailCellScale, mResultDesc->getFont()->getHeight() * 6.0f); // Make description text wrap at edge of container. mResultDesc->setSize(mDescContainer->getSize().x, 0.0f); // 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(3), resultNameSize.y); + mResultName->setSize(mGrid.getColWidth(1) + mGrid.getColWidth(2), mResultName->getSize().y); mGrid.onSizeChanged(); mBusyAnim.setSize(mSize); @@ -289,30 +288,30 @@ void GuiScraperSearch::updateViewStyle() // Add them back depending on search type. if (mSearchType == ALWAYS_ACCEPT_FIRST_RESULT) { // 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); // Need a border on the bottom left. mGrid.setEntry(std::make_shared(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. - mGrid.setEntry(mDescContainer, glm::ivec2{3, 0}, false, false, glm::ivec2{1, 3}, - GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM); + mGrid.setEntry(mDescContainer, glm::ivec2{4, 0}, false, false, glm::ivec2{1, 3}, + GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM | GridFlags::BORDER_LEFT); // Make description text wrap at edge of container. mResultDesc->setSize(mDescContainer->getSize().x, 0.0f); } else { // Fake row where name would be. mGrid.setEntry(std::make_shared(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. - 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); // 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); // Make description text wrap at edge of container. mResultDesc->setSize(mDescContainer->getSize().x, 0); @@ -798,6 +797,8 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params) stop(); mRefinedSearch = true; params.nameOverride = name; + if (mRefineCallback != nullptr) + mRefineCallback(); search(params); }; diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 449124ba0..082e8e3b0 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -71,6 +71,10 @@ public: { mCancelCallback = cancelCallback; } + void setRefineCallback(const std::function& refineCallback) + { + mRefineCallback = refineCallback; + } bool input(InputConfig* config, Input input) override; void update(int deltaTime) override; @@ -92,6 +96,8 @@ public: void onFocusGained() override { mGrid.onFocusGained(); } void onFocusLost() override { mGrid.onFocusLost(); } + std::shared_ptr& getResultList() { return mResultList; } + private: void updateViewStyle(); void updateThumbnail(); @@ -152,6 +158,7 @@ private: std::function mAcceptCallback; std::function mSkipCallback; std::function mCancelCallback; + std::function mRefineCallback; unsigned int mScrapeCount; bool mRefinedSearch; bool mBlockAccept; diff --git a/es-core/src/components/ComponentList.h b/es-core/src/components/ComponentList.h index 9035cd881..fd7739fc5 100644 --- a/es-core/src/components/ComponentList.h +++ b/es-core/src/components/ComponentList.h @@ -86,6 +86,13 @@ public: float getTotalRowHeight() const; 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& callback) { mCursorChangedCallback = callback; diff --git a/es-core/src/components/TextComponent.cpp b/es-core/src/components/TextComponent.cpp index fa15ce628..08aa17674 100644 --- a/es-core/src/components/TextComponent.cpp +++ b/es-core/src/components/TextComponent.cpp @@ -17,7 +17,6 @@ TextComponent::TextComponent(Window* window) , mFont{Font::get(FONT_SIZE_MEDIUM)} , mColor{0x000000FF} , mBgColor{0} - , mMargin{0.0f} , mRenderBackground{false} , mUppercase{false} , mAutoCalcExtent{1, 1} @@ -36,13 +35,11 @@ TextComponent::TextComponent(Window* window, Alignment align, glm::vec3 pos, glm::vec2 size, - unsigned int bgcolor, - float margin) + unsigned int bgcolor) : GuiComponent{window} , mFont{nullptr} , mColor{0x000000FF} , mBgColor{0} - , mMargin{margin} , mRenderBackground{false} , mUppercase{false} , mAutoCalcExtent{1, 1} @@ -238,12 +235,12 @@ void TextComponent::onTextChanged() // Abbreviate text. const std::string 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()); text.erase(newSize, text.size() - newSize); + if (!text.empty() && text.back() == ' ') + text.pop_back(); size = f->sizeText(text); } diff --git a/es-core/src/components/TextComponent.h b/es-core/src/components/TextComponent.h index cd07f5592..eb1694cdc 100644 --- a/es-core/src/components/TextComponent.h +++ b/es-core/src/components/TextComponent.h @@ -32,8 +32,7 @@ public: Alignment align = ALIGN_LEFT, glm::vec3 pos = {}, glm::vec2 size = {}, - unsigned int bgcolor = 0x00000000, - float margin = 0.0f); + unsigned int bgcolor = 0x00000000); void setFont(const std::shared_ptr& font); void setUppercase(bool uppercase); @@ -89,7 +88,6 @@ private: unsigned int mBgColor; unsigned char mColorOpacity; unsigned char mBgColorOpacity; - float mMargin; bool mRenderBackground; bool mUppercase;