mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 17:45:38 +00:00
Fixed a sneaky crash.
Added metadata display to ScraperSearchComponent.
This commit is contained in:
parent
1e8b040f73
commit
8e5c910de3
|
@ -4,10 +4,13 @@
|
|||
#include "TextComponent.h"
|
||||
#include "ScrollableContainer.h"
|
||||
#include "ImageComponent.h"
|
||||
#include "RatingComponent.h"
|
||||
#include "DateTimeComponent.h"
|
||||
#include "ComponentList.h"
|
||||
#include "../HttpReq.h"
|
||||
#include "../Settings.h"
|
||||
#include "../Log.h"
|
||||
#include "../Util.h"
|
||||
|
||||
ScraperSearchComponent::ScraperSearchComponent(Window* window, SearchType type) : GuiComponent(window),
|
||||
mGrid(window, Eigen::Vector2i(4, 3)),
|
||||
|
@ -36,6 +39,36 @@ ScraperSearchComponent::ScraperSearchComponent(Window* window, SearchType type)
|
|||
mDescContainer->addChild(mResultDesc.get());
|
||||
mDescContainer->setAutoScroll(2200, 0.015f);
|
||||
|
||||
// metadata
|
||||
auto font = Font::get(FONT_SIZE_SMALL); // this gets replaced in onSizeChanged() so its just a placeholder
|
||||
const unsigned int mdColor = 0x777777FF;
|
||||
const unsigned int mdLblColor = 0x666666FF;
|
||||
mMD_Rating = std::make_shared<RatingComponent>(mWindow);
|
||||
mMD_ReleaseDate = std::make_shared<DateTimeComponent>(mWindow);
|
||||
mMD_ReleaseDate->setColor(mdColor);
|
||||
mMD_Developer = std::make_shared<TextComponent>(mWindow, "", font, mdColor);
|
||||
mMD_Publisher = std::make_shared<TextComponent>(mWindow, "", font, mdColor);
|
||||
mMD_Genre = std::make_shared<TextComponent>(mWindow, "", font, mdColor);
|
||||
mMD_Players = std::make_shared<TextComponent>(mWindow, "", font, mdColor);
|
||||
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "RATING:", font, mdLblColor), mMD_Rating));
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "RELEASED:", font, mdLblColor), mMD_ReleaseDate));
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "DEVELOPER:", font, mdLblColor), mMD_Developer));
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "PUBLISHER:", font, mdLblColor), mMD_Publisher));
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "GENRE:", font, mdLblColor), mMD_Genre));
|
||||
mMD_Pairs.push_back(MetaDataPair(std::make_shared<TextComponent>(mWindow, "PLAYERS:", font, mdLblColor), mMD_Players));
|
||||
|
||||
mMD_Grid = std::make_shared<ComponentGrid>(mWindow, Vector2i(2, mMD_Pairs.size()));
|
||||
unsigned int i = 0;
|
||||
for(auto it = mMD_Pairs.begin(); it != mMD_Pairs.end(); it++)
|
||||
{
|
||||
mMD_Grid->setEntry(it->first, Vector2i(0, i), false, true);
|
||||
mMD_Grid->setEntry(it->second, Vector2i(1, i), false, true);
|
||||
i++;
|
||||
}
|
||||
|
||||
mGrid.setEntry(mMD_Grid, Vector2i(2, 1), false, true);
|
||||
|
||||
// result list
|
||||
mResultList = std::make_shared<ComponentList>(mWindow);
|
||||
|
||||
|
@ -57,8 +90,36 @@ void ScraperSearchComponent::onSizeChanged()
|
|||
mGrid.setRowHeightPerc(0, fontHeightPerc); // result name
|
||||
mGrid.setRowHeightPerc(2, 0.375f); // description
|
||||
|
||||
mResultThumbnail->setMaxSize(mGrid.getColWidth(1), mGrid.getRowHeight(1));
|
||||
// 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) - 16, mGrid.getRowHeight(1));
|
||||
mResultDesc->setSize(mDescContainer->getSize().x(), 0); // make desc text wrap at edge of container
|
||||
|
||||
// metadata
|
||||
// (mMD_Grid has already been resized by mGrid)
|
||||
|
||||
const int fontHeight = (int)(mMD_Grid->getSize().y() / mMD_Pairs.size() * 0.8f);
|
||||
auto fontLbl = Font::get(fontHeight, FONT_PATH_REGULAR);
|
||||
auto fontComp = Font::get(fontHeight, FONT_PATH_LIGHT);
|
||||
|
||||
// update label fonts
|
||||
float maxLblWidth = 0;
|
||||
for(auto it = mMD_Pairs.begin(); it != mMD_Pairs.end(); it++)
|
||||
{
|
||||
it->first->setFont(fontLbl);
|
||||
it->first->setSize(0, 0);
|
||||
if(it->first->getSize().x() > maxLblWidth)
|
||||
maxLblWidth = it->first->getSize().x() + 6;
|
||||
}
|
||||
|
||||
// update component fonts
|
||||
mMD_ReleaseDate->setFont(fontComp);
|
||||
mMD_Developer->setFont(fontComp);
|
||||
mMD_Publisher->setFont(fontComp);
|
||||
mMD_Genre->setFont(fontComp);
|
||||
mMD_Players->setFont(fontComp);
|
||||
|
||||
mMD_Grid->setColWidthPerc(0, maxLblWidth / mMD_Grid->getSize().x());
|
||||
}
|
||||
|
||||
void ScraperSearchComponent::updateViewStyle()
|
||||
|
@ -171,10 +232,27 @@ void ScraperSearchComponent::updateInfoPane()
|
|||
mThumbnailReq = std::unique_ptr<HttpReq>(new HttpReq(thumb));
|
||||
else
|
||||
mThumbnailReq.reset();
|
||||
|
||||
// metadata
|
||||
mMD_Rating->setValue(strToUpper(mScraperResults.at(i).mdl.get("rating")));
|
||||
mMD_ReleaseDate->setValue(strToUpper(mScraperResults.at(i).mdl.get("releasedate")));
|
||||
mMD_Developer->setText(strToUpper(mScraperResults.at(i).mdl.get("developer")));
|
||||
mMD_Publisher->setText(strToUpper(mScraperResults.at(i).mdl.get("publisher")));
|
||||
mMD_Genre->setText(strToUpper(mScraperResults.at(i).mdl.get("genre")));
|
||||
mMD_Players->setText(strToUpper(mScraperResults.at(i).mdl.get("players")));
|
||||
|
||||
}else{
|
||||
mResultName->setText("");
|
||||
mResultDesc->setText("");
|
||||
mResultThumbnail->setImage("");
|
||||
|
||||
// metadata
|
||||
mMD_Rating->setValue("");
|
||||
mMD_ReleaseDate->setValue("");
|
||||
mMD_Developer->setText("");
|
||||
mMD_Publisher->setText("");
|
||||
mMD_Genre->setText("");
|
||||
mMD_Players->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,14 +285,14 @@ void ScraperSearchComponent::render(const Eigen::Affine3f& parentTrans)
|
|||
{
|
||||
Eigen::Affine3f trans = parentTrans * getTransform();
|
||||
|
||||
renderChildren(trans);
|
||||
|
||||
if(mBlockAccept)
|
||||
{
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect((int)mResultList->getPosition().x(), (int)mResultList->getPosition().y(),
|
||||
(int)mResultList->getSize().x(), (int)mResultList->getSize().y(), 0x00000011);
|
||||
}
|
||||
|
||||
renderChildren(trans);
|
||||
}
|
||||
|
||||
void ScraperSearchComponent::returnResult(ScraperSearchResult result)
|
||||
|
@ -233,6 +311,8 @@ void ScraperSearchComponent::returnResult(ScraperSearchResult result)
|
|||
|
||||
void ScraperSearchComponent::update(int deltaTime)
|
||||
{
|
||||
GuiComponent::update(deltaTime);
|
||||
|
||||
if(mThumbnailReq && mThumbnailReq->status() != HttpReq::REQ_IN_PROGRESS)
|
||||
{
|
||||
updateThumbnail();
|
||||
|
@ -254,15 +334,14 @@ void ScraperSearchComponent::update(int deltaTime)
|
|||
{
|
||||
if(mMDResolveHandle->status() == ASYNC_DONE)
|
||||
{
|
||||
// this might end in us being deleted, depending on mAcceptCallback - so make sure this is the last thing we do in update()
|
||||
returnResult(mMDResolveHandle->getResult());
|
||||
}else if(mMDResolveHandle->status() == ASYNC_ERROR)
|
||||
{
|
||||
onSearchError(mMDResolveHandle->getStatusString());
|
||||
}
|
||||
mMDResolveHandle.reset();
|
||||
}
|
||||
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void ScraperSearchComponent::updateThumbnail()
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
#define MAX_SCRAPER_RESULTS 5
|
||||
|
||||
class ComponentList;
|
||||
class TextEditComponent;
|
||||
class ImageComponent;
|
||||
class RatingComponent;
|
||||
class TextComponent;
|
||||
class DateTimeComponent;
|
||||
class ScrollableContainer;
|
||||
class HttpReq;
|
||||
|
||||
|
||||
class ScraperSearchComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
|
@ -61,6 +64,18 @@ private:
|
|||
std::shared_ptr<ImageComponent> mResultThumbnail;
|
||||
std::shared_ptr<ComponentList> mResultList;
|
||||
|
||||
std::shared_ptr<ComponentGrid> mMD_Grid;
|
||||
std::shared_ptr<RatingComponent> mMD_Rating;
|
||||
std::shared_ptr<DateTimeComponent> mMD_ReleaseDate;
|
||||
std::shared_ptr<TextComponent> mMD_Developer;
|
||||
std::shared_ptr<TextComponent> mMD_Publisher;
|
||||
std::shared_ptr<TextComponent> mMD_Genre;
|
||||
std::shared_ptr<TextComponent> mMD_Players;
|
||||
|
||||
// label-component pair
|
||||
typedef std::pair< std::shared_ptr<TextComponent>, std::shared_ptr<GuiComponent> > MetaDataPair;
|
||||
std::vector<MetaDataPair> mMD_Pairs;
|
||||
|
||||
SearchType mSearchType;
|
||||
ScraperSearchParams mLastSearch;
|
||||
std::function<void(const ScraperSearchResult&)> mAcceptCallback;
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
GuiGameScraper::GuiGameScraper(Window* window, ScraperSearchParams params, std::function<void(const ScraperSearchResult&)> doneFunc) : GuiComponent(window),
|
||||
mGrid(window, Eigen::Vector2i(1, 3)),
|
||||
mBox(window, ":/frame.png"),
|
||||
mSearchParams(params)
|
||||
mSearchParams(params),
|
||||
mClose(false)
|
||||
{
|
||||
addChild(&mBox);
|
||||
addChild(&mGrid);
|
||||
|
@ -45,7 +46,29 @@ GuiGameScraper::GuiGameScraper(Window* window, ScraperSearchParams params, std::
|
|||
mGrid.setPosition((mSize.x() - mGrid.getSize().x()) / 2, (mSize.y() - mGrid.getSize().y()) / 2);
|
||||
mBox.fitTo(mGrid.getSize(), mGrid.getPosition(), Eigen::Vector2f(-32, -32));
|
||||
|
||||
mSearch->setAcceptCallback([this, doneFunc](const ScraperSearchResult& result) { doneFunc(result); delete this; });
|
||||
// we call this->close() instead of just delete this; in the accept callback:
|
||||
// this is because of how GuiComponent::update works. if it was just delete this, this would happen when the metadata resolver is done:
|
||||
// GuiGameScraper::update()
|
||||
// GuiComponent::update()
|
||||
// it = mChildren.begin();
|
||||
// mBox::update()
|
||||
// it++;
|
||||
// mSearchComponent::update()
|
||||
// acceptCallback -> delete this
|
||||
// it++; // error, mChildren has been deleted because it was part of this
|
||||
|
||||
// so instead we do this:
|
||||
// GuiGameScraper::update()
|
||||
// GuiComponent::update()
|
||||
// it = mChildren.begin();
|
||||
// mBox::update()
|
||||
// it++;
|
||||
// mSearchComponent::update()
|
||||
// acceptCallback -> close() -> mClose = true
|
||||
// it++; // ok
|
||||
// if(mClose)
|
||||
// delete this;
|
||||
mSearch->setAcceptCallback([this, doneFunc](const ScraperSearchResult& result) { doneFunc(result); close(); });
|
||||
mSearch->setCancelCallback([&] { delete this; });
|
||||
|
||||
mGrid.resetCursor();
|
||||
|
@ -63,7 +86,20 @@ bool GuiGameScraper::input(InputConfig* config, Input input)
|
|||
return GuiComponent::input(config, input);
|
||||
}
|
||||
|
||||
void GuiGameScraper::update(int deltaTime)
|
||||
{
|
||||
GuiComponent::update(deltaTime);
|
||||
|
||||
if(mClose)
|
||||
delete this;
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> GuiGameScraper::getHelpPrompts()
|
||||
{
|
||||
return mGrid.getHelpPrompts();
|
||||
}
|
||||
|
||||
void GuiGameScraper::close()
|
||||
{
|
||||
mClose = true;
|
||||
}
|
|
@ -10,10 +10,13 @@ public:
|
|||
GuiGameScraper(Window* window, ScraperSearchParams params, std::function<void(const ScraperSearchResult&)> doneFunc);
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
|
||||
void update(int deltaTime);
|
||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
|
||||
private:
|
||||
bool mClose;
|
||||
void close();
|
||||
|
||||
ComponentGrid mGrid;
|
||||
NinePatchComponent mBox;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ void MDResolveHandle::update()
|
|||
setStatus(ASYNC_DONE);
|
||||
}
|
||||
|
||||
std::unique_ptr<AsyncHandle> downloadImageAsync(const std::string& url, const std::string& saveAs)
|
||||
std::unique_ptr<ImageDownloadHandle> downloadImageAsync(const std::string& url, const std::string& saveAs)
|
||||
{
|
||||
return std::unique_ptr<ImageDownloadHandle>(new ImageDownloadHandle(url, saveAs,
|
||||
Settings::getInstance()->getInt("ScraperResizeWidth"), Settings::getInstance()->getInt("ScraperResizeHeight")));
|
||||
|
|
|
@ -84,7 +84,7 @@ private:
|
|||
std::string getSaveAsPath(const ScraperSearchParams& params, const std::string& suffix, const std::string& url);
|
||||
|
||||
//Will resize according to Settings::getInt("ScraperResizeWidth") and Settings::getInt("ScraperResizeHeight").
|
||||
std::unique_ptr<AsyncHandle> downloadImageAsync(const std::string& url, const std::string& saveAs);
|
||||
std::unique_ptr<ImageDownloadHandle> downloadImageAsync(const std::string& url, const std::string& saveAs);
|
||||
|
||||
// Resolves all metadata assets that need to be downloaded.
|
||||
std::unique_ptr<MDResolveHandle> resolveMetaDataAssets(const ScraperSearchResult& result, const ScraperSearchParams& search);
|
||||
|
|
Loading…
Reference in a new issue