Commit bbb8aeea authored by Aloshi's avatar Aloshi

Completely rewrote ComponentGrid to use shared pointers, have support for

borders, work better with nested components, and generally suck less.
Split the scraper screen into a "ScraperSearchComponent" so it can be reused in other menus (what could this possibly mean for the future?!).
Re-designed the ScraperSearchComponent to fit UI concepts.
Added the ability to put a row of buttons at the bottom of a MenuComponent.
Redid GuiMetaDataEd to use a MenuComponent instead of ComponentGrid.
Redid GuiGameScraper to use a ComponentGrid containing a ScraperSearchComponent.
Fixed Renderer::pushClipRect not clipping new rects to be within the bounds of the existing clipRect stack.
A ton of little fixes that I forgot to mention.
It's a good thing I'm the only developer currently, or I would have to actually break this into multiple commits.
parent 0626f619
......@@ -172,6 +172,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/OptionListComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScraperSearchComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.h
......@@ -252,6 +253,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/components/MenuComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScraperSearchComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.cpp
......
......@@ -133,51 +133,33 @@ boost::posix_time::ptime MetaDataList::getTime(const std::string& key) const
return string_to_ptime(get(key), "%Y%m%dT%H%M%S%F%q");
}
GuiComponent* MetaDataList::makeDisplay(Window* window, MetaDataType as)
std::shared_ptr<GuiComponent> MetaDataList::makeEditor(Window* window, MetaDataType as)
{
switch(as)
{
case MD_RATING:
{
RatingComponent* comp = new RatingComponent(window);
return comp;
}
default:
TextComponent* comp = new TextComponent(window);
return comp;
}
}
GuiComponent* MetaDataList::makeEditor(Window* window, MetaDataType as)
{
switch(as)
{
case MD_RATING:
{
RatingComponent* comp = new RatingComponent(window);
return comp;
return std::make_shared<RatingComponent>(window);
}
case MD_MULTILINE_STRING:
{
TextEditComponent* comp = new TextEditComponent(window);
auto comp = std::make_shared<TextEditComponent>(window);
comp->setSize(comp->getSize().x(), comp->getSize().y() * 3);
return comp;
}
case MD_DATE:
{
DateTimeComponent* comp = new DateTimeComponent(window);
return comp;
return std::make_shared<DateTimeComponent>(window);
}
case MD_TIME:
{
DateTimeComponent* comp = new DateTimeComponent(window);
auto comp = std::make_shared<DateTimeComponent>(window);
comp->setDisplayMode(DateTimeComponent::DISP_RELATIVE_TO_NOW);
return comp;
}
default:
{
TextEditComponent* comp = new TextEditComponent(window);
return comp;
return std::make_shared<TextEditComponent>(window);
}
}
}
......
......@@ -55,8 +55,7 @@ public:
float getFloat(const std::string& key) const;
boost::posix_time::ptime getTime(const std::string& key) const;
static GuiComponent* makeDisplay(Window* window, MetaDataType as);
static GuiComponent* makeEditor(Window* window, MetaDataType as);
static std::shared_ptr<GuiComponent> makeEditor(Window* window, MetaDataType as);
inline MetaDataListType getType() const { return mType; }
inline const std::vector<MetaDataDecl>& getMDD() const { return getMDDByType(getType()); }
......
......@@ -39,14 +39,31 @@ namespace Renderer {
if(box[3] == 0)
box[3] = Renderer::getScreenHeight() - box.y();
//TODO - make sure the box fits within clipStack.top(), and clip further accordingly!
//glScissor starts at the bottom left of the window
//so (0, 0, 1, 1) is the bottom left pixel
//everything else uses y+ = down, so flip it to be consistent
//rect.pos.y = Renderer::getScreenHeight() - rect.pos.y - rect.size.y;
box[1] = Renderer::getScreenHeight() - box.y() - box[3];
//make sure the box fits within clipStack.top(), and clip further accordingly
if(clipStack.size())
{
Eigen::Vector4i& top = clipStack.top();
if(top[0] > box[0])
box[0] = top[0];
if(top[1] > box[1])
box[1] = top[1];
if(top[0] + top[2] < box[0] + box[2])
box[2] = (top[0] + top[2]) - box[0];
if(top[1] + top[3] < box[1] + box[3])
box[3] = (top[1] + top[3]) - box[1];
}
if(box[2] < 0)
box[2] = 0;
if(box[3] < 0)
box[3] = 0;
clipStack.push(box);
glScissor(box[0], box[1], box[2], box[3]);
glEnable(GL_SCISSOR_TEST);
......
......@@ -2,12 +2,14 @@
#include "../Renderer.h"
#include "../Window.h"
ButtonComponent::ButtonComponent(Window* window) : GuiComponent(window),
ButtonComponent::ButtonComponent(Window* window, const std::string& text, const std::string& helpText, const std::function<void()>& func) : GuiComponent(window),
mBox(window, ":/button.png"),
mFocused(false),
mEnabled(true),
mTextColorFocused(0xFFFFFFFF), mTextColorUnfocused(0x777777FF)
{
setSize(64, 48);
setPressedFunc(func);
setText(text, helpText);
}
void ButtonComponent::onSizeChanged()
......@@ -24,7 +26,7 @@ bool ButtonComponent::input(InputConfig* config, Input input)
{
if(config->isMappedTo("a", input) && input.value != 0)
{
if(mPressedFunc)
if(mPressedFunc && mEnabled)
mPressedFunc();
return true;
}
......@@ -48,13 +50,34 @@ void ButtonComponent::setText(const std::string& text, const std::string& helpTe
void ButtonComponent::onFocusGained()
{
mFocused = true;
mBox.setImagePath(":/button_filled.png");
updateImage();
}
void ButtonComponent::onFocusLost()
{
mFocused = false;
mBox.setImagePath(":/button.png");
updateImage();
}
void ButtonComponent::setEnabled(bool enabled)
{
mEnabled = enabled;
updateImage();
}
void ButtonComponent::updateImage()
{
if(!mEnabled || !mPressedFunc)
{
mBox.setImagePath(":/button.png");
mBox.setCenterColor(0x770000FF);
mBox.setEdgeColor(0x770000FF);
return;
}
mBox.setCenterColor(0xFFFFFFFF);
mBox.setEdgeColor(0xFFFFFFFF);
mBox.setImagePath(mFocused ? ":/button_filled.png" : ":/button.png");
}
void ButtonComponent::render(const Eigen::Affine3f& parentTrans)
......
......@@ -8,10 +8,12 @@
class ButtonComponent : public GuiComponent
{
public:
ButtonComponent(Window* window);
ButtonComponent(Window* window, const std::string& text = "", const std::string& helpText = "", const std::function<void()>& func = nullptr);
void setPressedFunc(std::function<void()> f);
void setEnabled(bool enable);
bool input(InputConfig* config, Input input) override;
void render(const Eigen::Affine3f& parentTrans) override;
......@@ -28,10 +30,12 @@ private:
std::function<void()> mPressedFunc;
bool mFocused;
bool mEnabled;
unsigned int mTextColorFocused;
unsigned int mTextColorUnfocused;
unsigned int getCurTextColor() const;
void updateImage();
std::string mText;
std::string mHelpText;
......
This diff is collapsed.
......@@ -2,63 +2,87 @@
#include "../GuiComponent.h"
// Used to arrange a bunch of components in a spreadsheet-esque grid.
class ComponentGrid : public GuiComponent
namespace GridFlags
{
public:
ComponentGrid(Window* window, Eigen::Vector2i gridDimensions);
virtual ~ComponentGrid();
enum UpdateBehavior
enum UpdateType
{
UpdateAlways, UpdateFocused
UPDATE_ALWAYS,
UPDATE_WHEN_SELECTED,
UPDATE_NEVER
};
enum AlignmentType
enum Border : unsigned int
{
AlignLeft, AlignRight, AlignCenter
BORDER_NONE = 0,
BORDER_TOP = 1,
BORDER_BOTTOM = 2,
BORDER_LEFT = 4,
BORDER_RIGHT = 8
};
};
//DO NOT USE NEGATIVE NUMBERS FOR POSITION OR SIZE.
void setEntry(Eigen::Vector2i pos, Eigen::Vector2i size, GuiComponent* component, bool canFocus, AlignmentType align,
Eigen::Matrix<bool, 1, 2> autoFit = Eigen::Matrix<bool, 1, 2>(true, true), UpdateBehavior updateType = UpdateAlways);
// Used to arrange a bunch of components in a spreadsheet-esque grid.
class ComponentGrid : public GuiComponent
{
public:
ComponentGrid(Window* window, const Eigen::Vector2i& gridDimensions);
virtual ~ComponentGrid();
void removeEntriesIn(Eigen::Vector2i pos, Eigen::Vector2i size);
bool removeEntry(const std::shared_ptr<GuiComponent>& comp);
void onPositionChanged() override;
void setEntry(const std::shared_ptr<GuiComponent>& comp, const Eigen::Vector2i& pos, bool canFocus, bool resize = true,
const Eigen::Vector2i& size = Eigen::Vector2i(1, 1), unsigned int border = GridFlags::BORDER_NONE, GridFlags::UpdateType updateType = GridFlags::UPDATE_ALWAYS);
void textInput(const char* text) override;
bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const Eigen::Affine3f& parentTrans) override;
void forceColumnWidth(int col, unsigned int size);
void forceRowHeight(int row, unsigned int size);
void updateComponent(GuiComponent* cmp);
void onSizeChanged() override;
void resetCursor();
bool cursorValid();
GuiComponent* getSelectedComponent();
float getColWidth(int col);
float getRowHeight(int row);
void setColWidthPerc(int col, float width);
void setRowHeightPerc(int row, float height);
bool moveCursor(Eigen::Vector2i dir);
void setCursorTo(const std::shared_ptr<GuiComponent>& comp);
inline std::shared_ptr<GuiComponent> getSelectedComponent()
{
GridEntry* e = getCellAt(mCursor);
if(e)
return e->component;
else
return nullptr;
}
void moveCursor(Eigen::Vector2i dir);
void onFocusLost() override;
void onFocusGained() override;
virtual std::vector<HelpPrompt> getHelpPrompts() override;
private:
class ComponentEntry
class GridEntry
{
public:
Eigen::Vector2i pos;
Eigen::Vector2i dim;
GuiComponent* component;
UpdateBehavior updateType;
AlignmentType alignment;
std::shared_ptr<GuiComponent> component;
bool canFocus;
bool resize;
GridFlags::UpdateType updateType;
unsigned int border;
ComponentEntry() : component(NULL), updateType(UpdateAlways), canFocus(true), alignment(AlignCenter) {};
ComponentEntry(Eigen::Vector2i p, Eigen::Vector2i d, GuiComponent* comp, UpdateBehavior update, bool focus, AlignmentType align) : pos(p), dim(d), component(comp), updateType(update), canFocus(focus), alignment(align) {};
GridEntry(const Eigen::Vector2i& p = Eigen::Vector2i::Zero(), const Eigen::Vector2i& d = Eigen::Vector2i::Zero(),
const std::shared_ptr<GuiComponent>& cmp = nullptr, bool f = false, bool r = true,
GridFlags::UpdateType u = GridFlags::UPDATE_ALWAYS, unsigned int b = GridFlags::BORDER_NONE) :
pos(p), dim(d), component(cmp), canFocus(f), resize(r), updateType(u), border(b)
{};
operator bool() const
{
......@@ -66,30 +90,30 @@ private:
}
};
//Offset we render components by (for scrolling). [unimplemented]
Eigen::Vector2f mComponentOffset;
float* mRowHeights;
float* mColWidths;
struct Vert
{
Vert(float xi = 0, float yi = 0) : x(xi), y(yi) {};
float x;
float y;
};
Eigen::Vector2i mGridSize;
ComponentEntry** mGrid;
std::vector<ComponentEntry*> mEntries;
void makeCells(Eigen::Vector2i size);
void setCell(unsigned int x, unsigned int y, ComponentEntry* entry);
ComponentEntry* getCell(unsigned int x, unsigned int y);
std::vector<Vert> mLines;
std::vector<unsigned int> mLineColors;
unsigned int getColumnWidth(int col);
unsigned int getRowHeight(int row);
// Update position & size
void updateCellComponent(const GridEntry& cell);
void updateSeparators();
unsigned int* mColumnWidths;
unsigned int* mRowHeights;
bool* mColumnWidthForced;
bool* mRowHeightForced;
GridEntry* getCellAt(int x, int y);
inline GridEntry* getCellAt(const Eigen::Vector2i& pos) { return getCellAt(pos.x(), pos.y()); }
Eigen::Vector2i mGridSize;
Eigen::Vector3f getCellOffset(Eigen::Vector2i gridPos);
void updateSize();
std::vector<GridEntry> mCells;
void onCursorMoved(Eigen::Vector2i from, Eigen::Vector2i to);
Eigen::Vector2i mCursor;
void updateComponentOffsets();
void updateCellSize(ComponentEntry* e, bool updWidth = true, bool updHeight = true);
};
......@@ -6,6 +6,7 @@ ComponentList::ComponentList(Window* window) : IList<ComponentListRow, void*>(wi
{
mSelectorBarOffset = 0;
mCameraOffset = 0;
mFocused = false;
}
void ComponentList::addRow(const ComponentListRow& row, bool setCursorHere)
......@@ -41,6 +42,16 @@ void ComponentList::onSizeChanged()
onCursorChanged(mScrollVelocity != 0 ? CURSOR_SCROLLING : CURSOR_STOPPED);
}
void ComponentList::onFocusLost()
{
mFocused = false;
}
void ComponentList::onFocusGained()
{
mFocused = true;
}
bool ComponentList::input(InputConfig* config, Input input)
{
if(size() == 0)
......@@ -127,23 +138,27 @@ void ComponentList::render(const Eigen::Affine3f& parentTrans)
// draw our entries
renderChildren(trans);
// draw selector bar
// custom rendering
Renderer::setMatrix(trans);
// inversion: src * (1 - dst) + dst * 0 = where src = 1
// need a function that goes roughly 0x777777 -> 0xFFFFFF
// and 0xFFFFFF -> 0x777777
// (1 - dst) + 0x77
// draw selector bar
if(mFocused)
{
// inversion: src * (1 - dst) + dst * 0 = where src = 1
// need a function that goes roughly 0x777777 -> 0xFFFFFF
// and 0xFFFFFF -> 0x777777
// (1 - dst) + 0x77
const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data);
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)selectedRowHeight, 0xFFFFFFFF,
GL_ONE_MINUS_DST_COLOR, GL_ZERO);
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)selectedRowHeight, 0x777777FF,
GL_ONE, GL_ONE);
const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data);
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)selectedRowHeight, 0xFFFFFFFF,
GL_ONE_MINUS_DST_COLOR, GL_ZERO);
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)selectedRowHeight, 0x777777FF,
GL_ONE, GL_ONE);
// hack to draw 2px dark on left/right of the bar
Renderer::drawRect(0, (int)mSelectorBarOffset, 2, (int)selectedRowHeight, 0x878787FF);
Renderer::drawRect((int)mSize.x() - 2, (int)mSelectorBarOffset, 2, (int)selectedRowHeight, 0x878787FF);
// hack to draw 2px dark on left/right of the bar
Renderer::drawRect(0, (int)mSelectorBarOffset, 2, (int)selectedRowHeight, 0x878787FF);
Renderer::drawRect((int)mSize.x() - 2, (int)mSelectorBarOffset, 2, (int)selectedRowHeight, 0x878787FF);
}
// draw separators
float y = 0;
......
......@@ -52,11 +52,17 @@ public:
void render(const Eigen::Affine3f& parentTrans) override;
void onSizeChanged() override;
void onFocusGained() override;
void onFocusLost() override;
inline int getCursorId() const { return mCursor; }
protected:
void onCursorChanged(const CursorState& state) override;
private:
bool mFocused;
void updateElementPosition(const ComponentListRow& row);
void updateElementSize(const ComponentListRow& row);
......
#include "MenuComponent.h"
#include "ButtonComponent.h"
using namespace Eigen;
MenuComponent::MenuComponent(Window* window, const char* title) : GuiComponent(window),
mBackground(window), mTitle(window), mList(window)
{
mBackground(window), mGrid(window, Vector2i(1, 3))
{
addChild(&mBackground);
addChild(&mGrid);
mBackground.setImagePath(":/frame.png");
mTitle.setFont(Font::get(FONT_SIZE_LARGE));
mTitle.setText(title);
mTitle.setColor(0x555555FF);
mTitle.setCentered(true);
// set up title which will never change
mTitle = std::make_shared<TextComponent>(mWindow, title, Font::get(FONT_SIZE_LARGE), 0x555555FF, true);
mGrid.setEntry(mTitle, Vector2i(0, 0), false);
addChild(&mBackground);
addChild(&mTitle);
addChild(&mList);
// set up list which will never change (externally, anyway)
mList = std::make_shared<ComponentList>(mWindow);
mGrid.setEntry(mList, Vector2i(0, 1), true);
setSize(Renderer::getScreenWidth() * 0.5f, Renderer::getScreenHeight() * 0.75f);
updateGrid();
mGrid.resetCursor();
}
void MenuComponent::onSizeChanged()
{
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-32, -32));
const float titlePadding = mTitle.getFont()->getHeight() * 0.2f;
// update grid row/col sizes
mGrid.setRowHeightPerc(0, mTitle->getSize().y() / mSize.y());
mGrid.setRowHeightPerc(2, mButtonGrid ? (mButtonGrid->getSize().y() + 32) / mSize.y() : 0.07f);
mGrid.setSize(mSize);
}
void MenuComponent::addButton(const std::string& name, const std::string& helpText, const std::function<void()>& callback)
{
mButtons.push_back(std::make_shared<ButtonComponent>(mWindow, name, helpText, callback));
updateGrid();
onSizeChanged();
}
void MenuComponent::updateGrid()
{
if(mButtonGrid)
mGrid.removeEntry(mButtonGrid);
mTitle.setSize(mSize.x(), (float)mTitle.getFont()->getHeight());
mTitle.setPosition(0, titlePadding / 2);
if(mButtons.size())
{
mButtonGrid = std::make_shared<ComponentGrid>(mWindow, Vector2i(mButtons.size(), 1));
float buttonGridWidth = 16.0f * mButtons.size(); // initialize to padding
for(int i = 0; i < (int)mButtons.size(); i++)
{
mButtonGrid->setEntry(mButtons.at(i), Vector2i(i, 0), true, false);
buttonGridWidth += mButtons.at(i)->getSize().x();
}
mButtonGrid->setSize(buttonGridWidth, mButtons.at(0)->getSize().y());
mList.setPosition(0, mTitle.getSize().y() + titlePadding);
mList.setSize(mSize.x(), mSize.y() - mTitle.getSize().y() - titlePadding);
mGrid.setEntry(mButtonGrid, Vector2i(0, 2), true, false);
}else{
mButtonGrid.reset();
}
}
......@@ -3,6 +3,9 @@
#include "NinePatchComponent.h"
#include "ComponentList.h"
#include "TextComponent.h"
#include "ComponentGrid.h"
class ButtonComponent;
class MenuComponent : public GuiComponent
{
......@@ -11,7 +14,7 @@ public:
void onSizeChanged() override;
inline void addRow(const ComponentListRow& row, bool setCursorHere = false) { mList.addRow(row, setCursorHere); }
inline void addRow(const ComponentListRow& row, bool setCursorHere = false) { mList->addRow(row, setCursorHere); }
inline void addWithLabel(const std::string& label, const std::shared_ptr<GuiComponent>& comp, bool setCursorHere = false)
{
......@@ -21,8 +24,19 @@ public:
addRow(row, setCursorHere);
}
void addButton(const std::string& label, const std::string& helpText, const std::function<void()>& callback);
inline void setCursorToList() { mGrid.setCursorTo(mList); }
inline void setCursorToButtons() { assert(mButtonGrid); mGrid.setCursorTo(mButtonGrid); }
private:
void updateGrid();
NinePatchComponent mBackground;
TextComponent mTitle;
ComponentList mList;
ComponentGrid mGrid;
std::shared_ptr<TextComponent> mTitle;
std::shared_ptr<ComponentList> mList;
std::shared_ptr<ComponentGrid> mButtonGrid;
std::vector< std::shared_ptr<ButtonComponent> > mButtons;
};
#include "ScraperSearchComponent.h"
#include "../components/TextComponent.h"
#include "../components/ScrollableContainer.h"
#include "../components/ImageComponent.h"
#include "../components/ComponentList.h"
#include "../HttpReq.h"
#include "../Settings.h"
#include "../Log.h"
ScraperSearchComponent::ScraperSearchComponent(Window* window, SearchType type) : GuiComponent(window),
mGrid(window, Eigen::Vector2i(4, 3)),
mSearchType(type)
{
mSearchParams.system = NULL;
mSearchParams.game = NULL;
addChild(&mGrid);
using namespace Eigen;
// left spacer (empty component, needed for borders)
mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(0, 0), false, false, Vector2i(1, 3), GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM);
// selected result name
mResultName = std::make_shared<TextComponent>(mWindow, "Result name", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
mGrid.setEntry(mResultName, Vector2i(1, 0), false, true, Vector2i(2, 1), GridFlags::BORDER_TOP);
// selected result thumbnail
mResultThumbnail = std::make_shared<ImageComponent>(mWindow);
mGrid.setEntry(mResultThumbnail, Vector2i(1, 1), false, false, Vector2i(1, 1));
// selected result desc + container
mDescContainer = std::make_shared<ScrollableContainer>(mWindow);
mResultDesc = std::make_shared<TextComponent>(mWindow, "Result desc", Font::get(FONT_SIZE_SMALL), 0x777777FF);
mDescContainer->addChild(mResultDesc.get());
mDescContainer->setAutoScroll(2200, 0.015f);
// result list
mResultList = std::make_shared<ComponentList>(mWindow);
updateViewStyle();
}
void ScraperSearchComponent::onSizeChanged()
{
mGrid.setSize(mSize);
// column widths
mGrid.setColWidthPerc(0, 0.01f);
mGrid.setColWidthPerc(1, 0.25f);
mGrid.setColWidthPerc(2, 0.25f);
mGrid.setColWidthPerc(3, 0.49f);
// row heights
const float fontHeightPerc = (mResultName->getFont()->getHeight()) / mGrid.getSize().y();
mGrid.setRowHeightPerc(0, fontHeightPerc); // result name
mGrid.setRowHeightPerc(2, 0.375f); // description
mResultThumbnail->setMaxSize(mGrid.getColWidth(1), mGrid.getRowHeight(1));
mResultDesc->setSize(mDescContainer->getSize().x(), 0); // make desc text wrap at edge of container
}
void ScraperSearchComponent::updateViewStyle()
{
using namespace Eigen;
// unlink description and result list
mGrid.removeEntry(mResultDesc);
mGrid.removeEntry(mResultList);
// add them back depending on search type
if(mSearchType == ALWAYS_ACCEPT_FIRST_RESULT)
{
// show description on the right
mGrid.setEntry(mDescContainer, Vector2i(3, 0), false, true, Vector2i(1, 3), GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM);
mResultDesc->setSize(mDescContainer->getSize().x(), 0); // make desc text wrap at edge of container
}else{
// show result list on the right
mGrid.setEntry(mResultList, Vector2i(3, 0), true, true, Vector2i(1, 3), GridFlags::BORDER_LEFT | GridFlags::BORDER_TOP | GridFlags::BORDER_BOTTOM);
// show description under image/info
mGrid.setEntry(mDescContainer, Vector2i(1, 2), false, true, Vector2i(2, 1), GridFlags::BORDER_BOTTOM);
mResultDesc->setSize(mDescContainer->getSize().x(), 0); // make desc text wrap at edge of container
}
}
void ScraperSearchComponent::setSearchParams(const ScraperSearchParams& params)
{
mSearchParams = params;
search();
}
void ScraperSearchComponent::search()
{
Settings::getInstance()->getScraper()->getResultsAsync(mSearchParams, mWindow, std::bind(&ScraperSearchComponent::onSearchReceived, this, std::placeholders::_1));
}
void ScraperSearchComponent::onSearchReceived(std::vector<MetaDataList> results)
{
mResultList->clear();
mScraperResults = results;
const int end = results.size() > 5 ? 5 : results.size(); // at max display 5
auto font = Font::get(FONT_SIZE_MEDIUM);
unsigned int color = 0x777777FF;
if(end == 0)
{
ComponentListRow row;
row.addElement(std::make_shared<TextComponent>(mWindow, "No games found!", font, color), true);
mResultList->addRow(row);
mGrid.resetCursor();