Work on scraper UI integration (about there, just need a real scraper

now).
This commit is contained in:
Aloshi 2013-09-19 18:41:14 -05:00
parent 5dfaeeabb4
commit 3105073e50
17 changed files with 347 additions and 94 deletions

View file

@ -172,9 +172,11 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiFastSelect.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiInputConfig.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.h
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.hpp
@ -221,6 +223,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiFastSelect.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameScraper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiInputConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.cpp

View file

@ -5,7 +5,7 @@
#include <sstream>
GameData::GameData(SystemData* system, std::string path)
: mSystem(system), mPath(path), mBaseName(boost::filesystem::path(path).stem().string()), mMetaData(MetaDataList::getDefaultGameMDD())
: mSystem(system), mPath(path), mBaseName(boost::filesystem::path(path).stem().string()), mMetaData(system->getGameMDD())
{
if(mMetaData.get("name").empty())
mMetaData.set("name", mBaseName);

View file

@ -3,10 +3,11 @@
#include "pugiXML/pugixml.hpp"
#include "platform.h"
#include <boost/filesystem.hpp>
#include "scrapers/GamesDBScraper.h"
Settings* Settings::sInstance = NULL;
Settings::Settings()
Settings::Settings() : mScraper(NULL)
{
setDefaults();
loadFile();
@ -37,7 +38,10 @@ void Settings::setDefaults()
mIntMap["GameListSortIndex"] = 0;
mScraper = NULL; //TODO
if(mScraper)
delete mScraper;
mScraper = new GamesDBScraper(); //TODO
}
template <typename K, typename V>

View file

@ -334,3 +334,8 @@ bool SystemData::hasGamelist()
else
return true;
}
std::vector<MetaDataDecl> SystemData::getGameMDD()
{
return MetaDataList::getDefaultGameMDD();
}

View file

@ -5,6 +5,7 @@
#include <string>
#include "FolderData.h"
#include "Window.h"
#include "MetaData.h"
class GameData;
@ -21,6 +22,7 @@ public:
std::string getExtension();
std::string getGamelistPath();
bool hasGamelist();
std::vector<MetaDataDecl> getGameMDD();
void launchGame(Window* window, GameData* game);

View file

@ -155,7 +155,7 @@ void parseGamelist(SystemData* system)
game = createGameFromPath(path, system);
//load the metadata
*(game->metadata()) = MetaDataList::createFromXML(MetaDataList::getDefaultGameMDD(), gameNode);
*(game->metadata()) = MetaDataList::createFromXML(system->getGameMDD(), gameNode);
//make sure name gets set if one didn't exist
if(game->metadata()->get("name").empty())
@ -166,13 +166,13 @@ void parseGamelist(SystemData* system)
}
}
void addGameDataNode(pugi::xml_node& parent, const GameData* game)
void addGameDataNode(pugi::xml_node& parent, const GameData* game, SystemData* system)
{
//create game and add to parent node
pugi::xml_node newGame = parent.append_child("game");
//write metadata
const_cast<GameData*>(game)->metadata()->appendToXML(newGame, MetaDataList::getDefaultGameMDD());
const_cast<GameData*>(game)->metadata()->appendToXML(newGame, system->getGameMDD());
if(newGame.children().begin() == newGame.child("name") //first element is name
&& ++newGame.children().begin() == newGame.children().end() //theres only one element
@ -254,7 +254,7 @@ void updateGamelist(SystemData* system)
//either the game content was removed, because it needs to be updated,
//or didn't exist in the first place, so just add it
addGameDataNode(root, game);
addGameDataNode(root, game, system);
}
++fit;
}

View file

@ -22,7 +22,7 @@ void ButtonComponent::setPressedFunc(std::function<void()> f)
bool ButtonComponent::input(InputConfig* config, Input input)
{
if(config->isMappedTo("a", input))
if(config->isMappedTo("a", input) && input.value != 0)
{
if(mPressedFunc)
mPressedFunc();

View file

@ -13,6 +13,14 @@ ComponentListComponent::ComponentListComponent(Window* window, Eigen::Vector2i g
makeCells(gridDimensions);
}
ComponentListComponent::~ComponentListComponent()
{
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
delete *iter;
}
}
void ComponentListComponent::makeCells(Eigen::Vector2i size)
{
if(mGrid)
@ -57,7 +65,7 @@ void ComponentListComponent::setEntry(Eigen::Vector2i pos, Eigen::Vector2i size,
return;
}
ComponentEntry entry(Eigen::Vector2i(pos.x(), pos.y()), Eigen::Vector2i(size.x(), size.y()), component, updateType, canFocus, align);
ComponentEntry* entry = new ComponentEntry(Eigen::Vector2i(pos.x(), pos.y()), Eigen::Vector2i(size.x(), size.y()), component, updateType, canFocus, align);
mEntries.push_back(entry);
@ -65,7 +73,7 @@ void ComponentListComponent::setEntry(Eigen::Vector2i pos, Eigen::Vector2i size,
{
for(int x = pos.x(); x < pos.x() + size.x(); x++)
{
setCell(x, y, &mEntries.back());
setCell(x, y, mEntries.back());
}
}
@ -81,13 +89,40 @@ void ComponentListComponent::setEntry(Eigen::Vector2i pos, Eigen::Vector2i size,
// setColumnWidth(pos.x(), (unsigned int)component->getSize().x());
//if(autoFit.y() && (int)getRowHeight(pos.y()) < component->getSize().y())
// setRowHeight(pos.y(), (unsigned int)component->getSize().y());
updateCellSize(&mEntries.back(), autoFit.x(), autoFit.y());
updateCellSize(mEntries.back(), autoFit.x(), autoFit.y());
component->setPosition(getCellOffset(pos));
updateSize();
}
void ComponentListComponent::removeEntriesIn(Eigen::Vector2i pos, Eigen::Vector2i size)
{
auto iter = mEntries.begin();
while(iter != mEntries.end())
{
if((*iter)->pos.x() >= pos.x() && (*iter)->pos.x() < pos.x() + size.x()
&& (*iter)->pos.y() >= pos.y() && (*iter)->pos.y() < pos.y() + size.y())
{
delete *iter;
iter = mEntries.erase(iter);
}else{
iter++;
}
}
for(int y = pos.y(); y < pos.y() + size.y(); y++)
{
for(int x = pos.x(); x < pos.x() + size.x(); x++)
{
setCell(x, y, NULL);
}
}
if(!cursorValid())
resetCursor();
}
void ComponentListComponent::forceRowHeight(int row, unsigned int size)
{
mRowHeights[row] = size;
@ -99,7 +134,7 @@ void ComponentListComponent::forceRowHeight(int row, unsigned int size)
void ComponentListComponent::forceColumnWidth(int col, unsigned int size)
{
mColumnWidths[col] = size;
mRowHeightForced[col] = true;
mColumnWidthForced[col] = true;
updateSize();
updateComponentOffsets();
}
@ -174,7 +209,7 @@ void ComponentListComponent::updateComponentOffsets()
{
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
iter->component->setPosition(getCellOffset(iter->pos));
(*iter)->component->setPosition(getCellOffset((*iter)->pos));
}
}
@ -229,9 +264,9 @@ void ComponentListComponent::updateComponent(GuiComponent* cmp)
{
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
if(iter->component == cmp)
if((*iter)->component == cmp)
{
updateCellSize(&(*iter));
updateCellSize(*iter);
}
}
}
@ -277,7 +312,7 @@ void ComponentListComponent::resetCursor()
}
const Eigen::Vector2i origCursor = mCursor;
mCursor << mEntries.at(0).pos[0], mEntries.at(0).pos[1];
mCursor << mEntries.at(0)->pos[0], mEntries.at(0)->pos[1];
onCursorMoved(origCursor, mCursor);
}
@ -356,15 +391,15 @@ void ComponentListComponent::update(int deltaTime)
{
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
switch(iter->updateType)
switch((*iter)->updateType)
{
case UpdateAlways:
iter->component->update(deltaTime);
(*iter)->component->update(deltaTime);
break;
case UpdateFocused:
if(cursorValid() && getCell(mCursor.x(), mCursor.y())->component == iter->component)
iter->component->update(deltaTime);
if(cursorValid() && getCell(mCursor.x(), mCursor.y())->component == (*iter)->component)
(*iter)->component->update(deltaTime);
break;
}
}
@ -373,13 +408,9 @@ void ComponentListComponent::update(int deltaTime)
void ComponentListComponent::render(const Eigen::Affine3f& parentTrans)
{
Eigen::Affine3f trans = parentTrans * getTransform();
Renderer::setMatrix(trans);
Renderer::drawRect(0, 0, (int)getSize().x(), (int)getSize().y(), 0xFFFFFFAA);
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
iter->component->render(trans);
(*iter)->component->render(trans);
}

View file

@ -6,6 +6,7 @@ class ComponentListComponent : public GuiComponent
{
public:
ComponentListComponent(Window* window, Eigen::Vector2i gridDimensions);
virtual ~ComponentListComponent();
enum UpdateBehavior
{
@ -21,6 +22,8 @@ public:
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);
void removeEntriesIn(Eigen::Vector2i pos, Eigen::Vector2i size);
void onPositionChanged() override;
void textInput(const char* text) override;
@ -38,6 +41,8 @@ public:
GuiComponent* getSelectedComponent();
void moveCursor(Eigen::Vector2i dir);
private:
class ComponentEntry
{
@ -58,18 +63,16 @@ private:
}
};
//Offset we render components by (for scrolling).
//Offset we render components by (for scrolling). [unimplemented]
Eigen::Vector2f mComponentOffset;
Eigen::Vector2i mGridSize;
ComponentEntry** mGrid;
std::vector<ComponentEntry> mEntries;
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);
Eigen::Vector2i mSelectedCellIndex;
unsigned int getColumnWidth(int col);
unsigned int getRowHeight(int row);
@ -81,7 +84,6 @@ private:
Eigen::Vector3f getCellOffset(Eigen::Vector2i gridPos);
void updateSize();
void moveCursor(Eigen::Vector2i dir);
void onCursorMoved(Eigen::Vector2i from, Eigen::Vector2i to);
Eigen::Vector2i mCursor;
@ -100,43 +102,15 @@ private:
// scroll to prev/next selectable component in grid Y
// if input == left/right
// scroll to prev/next selectable component in grid X
// if input == accept
// call registered function?
//entry struct/class
// GuiComponent* component - component to work with
// bool canFocus - can we pass input to this? (necessary for labels to not be selectable)
// Function* selectFunc?
// UpdateBehavior update - how to handle updates (all the time or only when focused)
//update
//animate component offset to display selected component within the bounds
//pass update to all entries with appropriate update behavior
//render
//clip rect to our size
//render a "selected" effect behind component with focus somehow
// an edge filter would be cool, but we can't really do that without shader support
// a transparent rect will work for now, but it's kind of ugly...
//glTranslatef by our render offset
// doesn't handle getGlobalOffset for our components...would need parenting for that
//methods
//List::setEntry(Vector2i gridPos, GuiComponent* component, bool canFocus, AlignmentType align,
// Function* selectFunc = NULL, UpdateBehavior updateType = UpdateAlways);
//example of setting up the SettingsMenu list:
//ComponentListComponent list;
//int row = 0;
//TextComponent* label = new TextComponent(Vector2i(0, 0), "Debug:", font, lblColor, etc);
//
//list.setEntry(Vector2i(-1, row), label, false, AlignRight);
//list.setEntry(Vector2i(0, row++), &mDebugSwitch, true, AlignLeft);
//...
//list.setEntry(Rect(-1, row, 2, 1), &mSaveButton, true, AlignCenter);
//example of setting up GameGrid list:
//ComponentListComponent list;
//for(int y = 0; y < yMax; y++)
// for(int x = 0; x < xMax; x++)
// list.setEntry(Vector2i(x, y), getGameImage(x, y), true, AlignCenter, &this->onSelectGame);

View file

@ -132,7 +132,7 @@ bool GuiGameList::input(InputConfig* config, Input input)
ScraperSearchParams searchParams;
searchParams.game = game;
searchParams.system = mSystem;
mWindow->pushGui(new GuiMetaDataEd(mWindow, game->metadata(), MetaDataList::getDefaultGameMDD(), searchParams, game->getBaseName(),
mWindow->pushGui(new GuiMetaDataEd(mWindow, game->metadata(), mSystem->getGameMDD(), searchParams, game->getBaseName(),
[&] { updateDetailData(); },
[game, root, this] { root->removeFileRecursive(game); updateList(); }
));

View file

@ -0,0 +1,168 @@
#include "GuiGameScraper.h"
#include "../Renderer.h"
#include "../Log.h"
#include "../scrapers/Scraper.h"
#include "../Settings.h"
#define RESULT_COUNT 5
GuiGameScraper::GuiGameScraper(Window* window, ScraperSearchParams params, std::function<void(MetaDataList)> doneFunc, std::function<void()> skipFunc) : GuiComponent(window),
mList(window, Eigen::Vector2i(2, 7 + RESULT_COUNT)),
mBox(window, ":/frame.png"),
mHeader(window, params.game->getBaseName(), Font::get(*window->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_MEDIUM)),
mResultName(window, "", Font::get(*window->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_MEDIUM)),
mResultInfo(window),
mResultDesc(window, "", Font::get(*window->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_SMALL)),
mSearchLabel(window, "Search for: ", Font::get(*window->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_SMALL)),
mSearchText(window),
mSearchParams(params),
mDoneFunc(doneFunc),
mSkipFunc(skipFunc)
{
// FILE NAME
//--------------------------------------
//Name................. |
//Desc................. | PREVIEW
//..................... | IMAGE?
//....(autoscroll)..... |
//--------------------------------------
//Search for: [_______________________]
//--------------------------------------
//Result #1 Name
//Result #2 Name
//Result #3 Name
//Result #4 Name
//Result #5 Name
addChild(&mBox);
addChild(&mList);
float sw = (float)Renderer::getScreenWidth();
float sh = (float)Renderer::getScreenHeight();
float colWidth = sw * 0.35f;
mList.forceColumnWidth(0, (unsigned int)colWidth);
mList.forceColumnWidth(1, (unsigned int)colWidth);
using namespace Eigen;
mList.setEntry(Vector2i(0, 0), Vector2i(2, 1), &mHeader, false, ComponentListComponent::AlignCenter);
//y = 1 is a spacer row
mResultName.setText(params.game->getName());
mResultName.setColor(0x3B56CCFF);
mList.setEntry(Vector2i(0, 1), Vector2i(1, 1), &mResultName, false, ComponentListComponent::AlignLeft);
mResultDesc.setText(params.game->metadata()->get("desc"));
mResultDesc.setSize(colWidth, 0);
mResultInfo.addChild(&mResultDesc);
mResultInfo.setSize(mResultDesc.getSize().x(), mResultDesc.getFont()->getHeight() * 3.0f);
mList.setEntry(Vector2i(0, 2), Vector2i(1, 1), &mResultInfo, false, ComponentListComponent::AlignLeft);
//y = 3 is a spacer row
mList.setEntry(Vector2i(0, 4), Vector2i(1, 1), &mSearchLabel, false, ComponentListComponent::AlignLeft);
mSearchText.setValue(!params.nameOverride.empty() ? params.nameOverride : params.game->getBaseName());
mSearchText.setSize(colWidth * 2 - mSearchLabel.getSize().x() - 20, mSearchText.getSize().y());
mList.setEntry(Vector2i(1, 4), Vector2i(1, 1), &mSearchText, true, ComponentListComponent::AlignRight);
//y = 5 is a spacer row
std::shared_ptr<Font> font = Font::get(*window->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_SMALL);
mResultNames.reserve(RESULT_COUNT);
for(int i = 0; i < RESULT_COUNT; i ++)
{
mResultNames.push_back(TextComponent(mWindow, "RESULT...", font));
mResultNames.at(i).setColor(0x111111FF);
mList.forceRowHeight(6 + i, (unsigned int)mResultNames.at(i).getSize().y());
}
mList.setPosition((sw - mList.getSize().x()) / 2, (sh - mList.getSize().y()) / 2);
mBox.fitTo(mList.getSize(), mList.getPosition());
mResultInfo.setAutoScroll(2200, 0.015f);
}
void GuiGameScraper::search()
{
//update mSearchParams
mSearchParams.nameOverride = mSearchText.getValue();
Settings::getInstance()->getScraper()->getResultsAsync(mSearchParams, mWindow, std::bind(&GuiGameScraper::onSearchDone, this, std::placeholders::_1));
}
void GuiGameScraper::onSearchDone(std::vector<MetaDataList> results)
{
mList.removeEntriesIn(Eigen::Vector2i(0, 6), Eigen::Vector2i(1, 5));
mScraperResults = results;
const int end = results.size() > 5 ? 5 : results.size(); //at max display 5
if(end == 0)
{
mResultNames.at(0).setText("No games found!");
mList.setEntry(Eigen::Vector2i(0, 6), Eigen::Vector2i(1, 1), &mResultNames.at(0), false, ComponentListComponent::AlignLeft);
}else{
for(int i = 0; i < end; i++)
{
mResultNames.at(i).setText(results.at(i).get("name"));
mList.setEntry(Eigen::Vector2i(0, 6 + i), Eigen::Vector2i(1, 1), &mResultNames.at(i), true, ComponentListComponent::AlignLeft);
}
}
}
int GuiGameScraper::getSelectedIndex()
{
int index = 0;
for(auto iter = mResultNames.begin(); iter != mResultNames.end(); iter++, index++)
{
if(&(*iter) == mList.getSelectedComponent())
return index;
}
return -1;
}
bool GuiGameScraper::input(InputConfig* config, Input input)
{
if(config->isMappedTo("a", input) && input.value != 0)
{
//if you're on a result
if(getSelectedIndex())
{
mDoneFunc(mScraperResults.at(getSelectedIndex()));
delete this;
return true;
}
}else if(config->isMappedTo("b", input) && input.value != 0)
{
if(mSkipFunc)
mSkipFunc();
delete this;
return true;
}
bool ret = GuiComponent::input(config, input);
if(config->isMappedTo("up", input) || config->isMappedTo("down", input))
{
//update game info pane
int i = getSelectedIndex();
if(i != -1)
{
mResultName.setText(mScraperResults.at(i).get("name"));
mResultDesc.setText(mScraperResults.at(i).get("desc"));
mResultInfo.setScrollPos(Eigen::Vector2d(0, 0));
mResultInfo.resetAutoScrollTimer();
}
}
return ret;
}

View file

@ -0,0 +1,44 @@
#pragma once
#include "../GuiComponent.h"
#include "../scrapers/Scraper.h"
#include "ComponentListComponent.h"
#include "TextComponent.h"
#include "ScrollableContainer.h"
#include "TextEditComponent.h"
#include "NinePatchComponent.h"
#include "../Settings.h"
class GuiGameScraper : public GuiComponent
{
public:
GuiGameScraper(Window* window, ScraperSearchParams params, std::function<void(MetaDataList)> doneFunc, std::function<void()> skipFunc = NULL);
bool input(InputConfig* config, Input input) override;
void search();
private:
int getSelectedIndex();
void onSearchDone(std::vector<MetaDataList> results);
ComponentListComponent mList;
NinePatchComponent mBox;
TextComponent mHeader;
TextComponent mResultName;
ScrollableContainer mResultInfo;
TextComponent mResultDesc;
TextComponent mSearchLabel;
TextEditComponent mSearchText;
std::vector<TextComponent> mResultNames;
ScraperSearchParams mSearchParams;
std::vector<MetaDataList> mScraperResults;
std::function<void(MetaDataList)> mDoneFunc;
std::function<void()> mSkipFunc;
};

View file

@ -3,6 +3,7 @@
#include "../Log.h"
#include "AsyncReqComponent.h"
#include "../Settings.h"
#include "GuiGameScraper.h"
#define MDED_RESERVED_ROWS 3
@ -10,28 +11,19 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
const std::string& header, std::function<void()> saveCallback, std::function<void()> deleteFunc) : GuiComponent(window),
mScraperParams(scraperParams),
mBox(mWindow, ":/frame.png", 0xAAAAAAFF, 0xCCCCCCFF),
mList(window, Eigen::Vector2i(3, mdd.size() + MDED_RESERVED_ROWS)),
mList(window, Eigen::Vector2i(2, mdd.size() + MDED_RESERVED_ROWS)),
mHeader(window),
mMetaDataDecl(mdd),
mMetaData(md),
mSavedCallback(saveCallback), mDeleteFunc(deleteFunc),
mDeleteButton(window), mFetchButton(window), mSaveButton(window)
{
LOG(LogInfo) << "Creating GuiMetaDataEd";
//set size to 80% by 80% of the window
mSize << Renderer::getScreenWidth() * 0.8f, Renderer::getScreenHeight() * 0.8f;
//center us
mPosition << (Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2, 0.0f;
unsigned int sw = Renderer::getScreenWidth();
unsigned int sh = Renderer::getScreenHeight();
addChild(&mBox);
mBox.fitTo(mSize);
//initialize path display
addChild(&mHeader);
mHeader.setPosition(0, 0);
mHeader.setSize(mSize.x(), 0);
mHeader.setCentered(true);
mHeader.setText(header);
//initialize buttons
@ -39,8 +31,8 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
if(mDeleteFunc)
mDeleteButton.setPressedFunc([&] { mDeleteFunc(); delete this; });
mFetchButton.setText("FETCH", 0x555555FF);
mFetchButton.setPressedFunc([&] { fetch(); });
mFetchButton.setText("FETCH", 0x00FF00FF);
mFetchButton.setPressedFunc(std::bind(&GuiMetaDataEd::fetch, this));
mSaveButton.setText("SAVE", 0x0000FFFF);
mSaveButton.setPressedFunc([&] { save(); delete this; });
@ -48,12 +40,26 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
//initialize metadata list
addChild(&mList);
populateList(mdd);
mList.setPosition((mSize.x() - mList.getSize().x()) / 2, mHeader.getSize().y() + 4);
mList.setPosition((sw - mList.getSize().x()) / 2.0f, (sh - mList.getSize().y()) / 2.0f); //center it
mList.resetCursor();
mBox.fitTo(mList.getSize(), mList.getPosition(), Eigen::Vector2f(12, 12));
mHeader.setPosition(mList.getPosition());
mHeader.setSize(mList.getSize().x(), 0);
mHeader.setCentered(true);
}
GuiMetaDataEd::~GuiMetaDataEd()
{
LOG(LogInfo) << "Deleted GuiMetaDataEd";
for(auto iter = mLabels.begin(); iter != mLabels.end(); iter++)
{
delete *iter;
}
for(auto iter = mEditors.begin(); iter != mEditors.end(); iter++)
{
delete *iter;
}
}
void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
@ -71,11 +77,11 @@ void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
int y = 0;
//delete button
mList.setEntry(Vector2i(0, y), Vector2i(1, 1), &mDeleteButton, true, ComponentListComponent::AlignCenter);
//fetch button
mList.setEntry(Vector2i(1, y), Vector2i(1, 1), &mFetchButton, true, ComponentListComponent::AlignCenter);
mList.setEntry(Vector2i(0, y), Vector2i(1, 1), &mFetchButton, true, ComponentListComponent::AlignLeft);
//delete button
mList.setEntry(Vector2i(1, y), Vector2i(1, 1), &mDeleteButton, true, ComponentListComponent::AlignRight);
y++;
@ -87,7 +93,7 @@ void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
mLabels.push_back(label);
GuiComponent* ed = MetaDataList::makeEditor(mWindow, iter->type);
ed->setSize(mSize.x() / 2, ed->getSize().y());
ed->setSize(Renderer::getScreenWidth() * 0.4f, ed->getSize().y());
ed->setValue(mMetaData->get(iter->key));
mList.setEntry(Vector2i(1, y), Vector2i(1, 1), ed, true, ComponentListComponent::AlignRight);
mEditors.push_back(ed);
@ -112,11 +118,16 @@ void GuiMetaDataEd::save()
void GuiMetaDataEd::fetch()
{
Settings::getInstance()->getScraper()->getResultsAsync(mScraperParams, mWindow, std::bind(&GuiMetaDataEd::fetchDone, this, std::placeholders::_1));
GuiGameScraper* scr = new GuiGameScraper(mWindow, mScraperParams, std::bind(&GuiMetaDataEd::fetchDone, this, std::placeholders::_1));
mWindow->pushGui(scr);
scr->search();
}
void GuiMetaDataEd::fetchDone(std::vector<MetaDataList> results)
void GuiMetaDataEd::fetchDone(MetaDataList result)
{
for(unsigned int i = 0; i < mEditors.size(); i++)
{
const std::string key = mMetaDataDecl.at(i).key;
mEditors.at(i)->setValue(result.get(key));
}
}

View file

@ -20,7 +20,7 @@ public:
private:
void save();
void fetch();
void fetchDone(std::vector<MetaDataList> results);
void fetchDone(MetaDataList result);
void populateList(const std::vector<MetaDataDecl>& mdd);
@ -35,6 +35,7 @@ private:
std::vector<TextComponent*> mLabels;
std::vector<GuiComponent*> mEditors;
std::vector<MetaDataDecl> mMetaDataDecl;
MetaDataList* mMetaData;
std::function<void()> mSavedCallback;
std::function<void()> mDeleteFunc;

View file

@ -101,7 +101,7 @@ void TextComponent::onTextChanged()
calculateExtent();
std::shared_ptr<Font> f = getFont();
mTextCache = std::unique_ptr<TextCache>(f->buildTextCache(f->wrapText(mText, mSize.x()), 0, 0, (mColor >> 8 << 8) | mOpacity));
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(mText, mSize.x()), 0, 0, (mColor >> 8 << 8) | mOpacity));
}
void TextComponent::setValue(const std::string& value)

View file

@ -8,7 +8,7 @@ class TextComponent : public GuiComponent
{
public:
TextComponent(Window* window);
TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, Eigen::Vector3f pos, Eigen::Vector2f size);
TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero());
void setFont(std::shared_ptr<Font> font);
void onSizeChanged() override;
@ -21,9 +21,9 @@ public:
std::string getValue() const override;
void setValue(const std::string& value) override;
private:
std::shared_ptr<Font> getFont() const;
private:
void calculateExtent();
void onTextChanged();
@ -32,7 +32,7 @@ private:
std::shared_ptr<Font> mFont;
Eigen::Matrix<bool, 1, 2> mAutoCalcExtent;
std::string mText;
std::unique_ptr<TextCache> mTextCache;
std::shared_ptr<TextCache> mTextCache;
bool mCentered;
};

View file

@ -1,5 +1,6 @@
#include "GamesDBScraper.h"
#include "../components/AsyncReqComponent.h"
#include "../Log.h"
std::vector<MetaDataList> GamesDBScraper::getResults(ScraperSearchParams params)
{
@ -18,6 +19,16 @@ std::vector<MetaDataList> GamesDBScraper::parseReq(ScraperSearchParams params, s
{
std::vector<MetaDataList> mdl;
MetaDataList md(params.system->getGameMDD());
md.set("name", "JUNK RESULT #1");
md.set("desc", "Black triangles");
mdl.push_back(md);
MetaDataList md2(params.system->getGameMDD());
md2.set("name", "JUNK RESULT #2");
md2.set("desc", "Test results are very exciting. Sort of. A little. If you squint. A lot.");
mdl.push_back(md2);
return mdl;
}
@ -34,4 +45,3 @@ void GamesDBScraper::getResultsAsync(ScraperSearchParams params, Window* window,
window->pushGui(req);
}