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/GuiFastSelect.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.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/GuiInputConfig.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.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/scrapers/GamesDBScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.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/GuiFastSelect.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMetaDataEd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.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/GuiInputConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.cpp

View file

@ -5,7 +5,7 @@
#include <sstream> #include <sstream>
GameData::GameData(SystemData* system, std::string path) 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()) if(mMetaData.get("name").empty())
mMetaData.set("name", mBaseName); mMetaData.set("name", mBaseName);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,6 +13,14 @@ ComponentListComponent::ComponentListComponent(Window* window, Eigen::Vector2i g
makeCells(gridDimensions); makeCells(gridDimensions);
} }
ComponentListComponent::~ComponentListComponent()
{
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
delete *iter;
}
}
void ComponentListComponent::makeCells(Eigen::Vector2i size) void ComponentListComponent::makeCells(Eigen::Vector2i size)
{ {
if(mGrid) if(mGrid)
@ -57,7 +65,7 @@ void ComponentListComponent::setEntry(Eigen::Vector2i pos, Eigen::Vector2i size,
return; 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); 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++) 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()); // setColumnWidth(pos.x(), (unsigned int)component->getSize().x());
//if(autoFit.y() && (int)getRowHeight(pos.y()) < component->getSize().y()) //if(autoFit.y() && (int)getRowHeight(pos.y()) < component->getSize().y())
// setRowHeight(pos.y(), (unsigned int)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)); component->setPosition(getCellOffset(pos));
updateSize(); 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) void ComponentListComponent::forceRowHeight(int row, unsigned int size)
{ {
mRowHeights[row] = size; mRowHeights[row] = size;
@ -99,7 +134,7 @@ void ComponentListComponent::forceRowHeight(int row, unsigned int size)
void ComponentListComponent::forceColumnWidth(int col, unsigned int size) void ComponentListComponent::forceColumnWidth(int col, unsigned int size)
{ {
mColumnWidths[col] = size; mColumnWidths[col] = size;
mRowHeightForced[col] = true; mColumnWidthForced[col] = true;
updateSize(); updateSize();
updateComponentOffsets(); updateComponentOffsets();
} }
@ -174,7 +209,7 @@ void ComponentListComponent::updateComponentOffsets()
{ {
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++) 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++) 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; 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); onCursorMoved(origCursor, mCursor);
} }
@ -356,15 +391,15 @@ void ComponentListComponent::update(int deltaTime)
{ {
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++) for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{ {
switch(iter->updateType) switch((*iter)->updateType)
{ {
case UpdateAlways: case UpdateAlways:
iter->component->update(deltaTime); (*iter)->component->update(deltaTime);
break; break;
case UpdateFocused: case UpdateFocused:
if(cursorValid() && getCell(mCursor.x(), mCursor.y())->component == iter->component) if(cursorValid() && getCell(mCursor.x(), mCursor.y())->component == (*iter)->component)
iter->component->update(deltaTime); (*iter)->component->update(deltaTime);
break; break;
} }
} }
@ -373,13 +408,9 @@ void ComponentListComponent::update(int deltaTime)
void ComponentListComponent::render(const Eigen::Affine3f& parentTrans) void ComponentListComponent::render(const Eigen::Affine3f& parentTrans)
{ {
Eigen::Affine3f trans = parentTrans * getTransform(); 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++) 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: public:
ComponentListComponent(Window* window, Eigen::Vector2i gridDimensions); ComponentListComponent(Window* window, Eigen::Vector2i gridDimensions);
virtual ~ComponentListComponent();
enum UpdateBehavior enum UpdateBehavior
{ {
@ -21,6 +22,8 @@ public:
void setEntry(Eigen::Vector2i pos, Eigen::Vector2i size, GuiComponent* component, bool canFocus, AlignmentType align, 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); 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 onPositionChanged() override;
void textInput(const char* text) override; void textInput(const char* text) override;
@ -38,6 +41,8 @@ public:
GuiComponent* getSelectedComponent(); GuiComponent* getSelectedComponent();
void moveCursor(Eigen::Vector2i dir);
private: private:
class ComponentEntry 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::Vector2f mComponentOffset;
Eigen::Vector2i mGridSize; Eigen::Vector2i mGridSize;
ComponentEntry** mGrid; ComponentEntry** mGrid;
std::vector<ComponentEntry> mEntries; std::vector<ComponentEntry*> mEntries;
void makeCells(Eigen::Vector2i size); void makeCells(Eigen::Vector2i size);
void setCell(unsigned int x, unsigned int y, ComponentEntry* entry); void setCell(unsigned int x, unsigned int y, ComponentEntry* entry);
ComponentEntry* getCell(unsigned int x, unsigned int y); ComponentEntry* getCell(unsigned int x, unsigned int y);
Eigen::Vector2i mSelectedCellIndex;
unsigned int getColumnWidth(int col); unsigned int getColumnWidth(int col);
unsigned int getRowHeight(int row); unsigned int getRowHeight(int row);
@ -81,7 +84,6 @@ private:
Eigen::Vector3f getCellOffset(Eigen::Vector2i gridPos); Eigen::Vector3f getCellOffset(Eigen::Vector2i gridPos);
void updateSize(); void updateSize();
void moveCursor(Eigen::Vector2i dir);
void onCursorMoved(Eigen::Vector2i from, Eigen::Vector2i to); void onCursorMoved(Eigen::Vector2i from, Eigen::Vector2i to);
Eigen::Vector2i mCursor; Eigen::Vector2i mCursor;
@ -100,43 +102,15 @@ private:
// scroll to prev/next selectable component in grid Y // scroll to prev/next selectable component in grid Y
// if input == left/right // if input == left/right
// scroll to prev/next selectable component in grid X // scroll to prev/next selectable component in grid X
// if input == accept
// call registered function?
//entry struct/class //entry struct/class
// GuiComponent* component - component to work with // GuiComponent* component - component to work with
// bool canFocus - can we pass input to this? (necessary for labels to not be selectable) // 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) // UpdateBehavior update - how to handle updates (all the time or only when focused)
//update //update
//animate component offset to display selected component within the bounds
//pass update to all entries with appropriate update behavior //pass update to all entries with appropriate update behavior
//render //render
//clip rect to our size //clip rect to our size
//render a "selected" effect behind component with focus somehow //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; ScraperSearchParams searchParams;
searchParams.game = game; searchParams.game = game;
searchParams.system = mSystem; 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(); }, [&] { updateDetailData(); },
[game, root, this] { root->removeFileRecursive(game); updateList(); } [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 "../Log.h"
#include "AsyncReqComponent.h" #include "AsyncReqComponent.h"
#include "../Settings.h" #include "../Settings.h"
#include "GuiGameScraper.h"
#define MDED_RESERVED_ROWS 3 #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), const std::string& header, std::function<void()> saveCallback, std::function<void()> deleteFunc) : GuiComponent(window),
mScraperParams(scraperParams), mScraperParams(scraperParams),
mBox(mWindow, ":/frame.png", 0xAAAAAAFF, 0xCCCCCCFF), 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), mHeader(window),
mMetaDataDecl(mdd),
mMetaData(md), mMetaData(md),
mSavedCallback(saveCallback), mDeleteFunc(deleteFunc), mSavedCallback(saveCallback), mDeleteFunc(deleteFunc),
mDeleteButton(window), mFetchButton(window), mSaveButton(window) mDeleteButton(window), mFetchButton(window), mSaveButton(window)
{ {
LOG(LogInfo) << "Creating GuiMetaDataEd"; unsigned int sw = Renderer::getScreenWidth();
unsigned int sh = Renderer::getScreenHeight();
//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;
addChild(&mBox); addChild(&mBox);
mBox.fitTo(mSize);
//initialize path display
addChild(&mHeader); addChild(&mHeader);
mHeader.setPosition(0, 0);
mHeader.setSize(mSize.x(), 0);
mHeader.setCentered(true);
mHeader.setText(header); mHeader.setText(header);
//initialize buttons //initialize buttons
@ -39,8 +31,8 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
if(mDeleteFunc) if(mDeleteFunc)
mDeleteButton.setPressedFunc([&] { mDeleteFunc(); delete this; }); mDeleteButton.setPressedFunc([&] { mDeleteFunc(); delete this; });
mFetchButton.setText("FETCH", 0x555555FF); mFetchButton.setText("FETCH", 0x00FF00FF);
mFetchButton.setPressedFunc([&] { fetch(); }); mFetchButton.setPressedFunc(std::bind(&GuiMetaDataEd::fetch, this));
mSaveButton.setText("SAVE", 0x0000FFFF); mSaveButton.setText("SAVE", 0x0000FFFF);
mSaveButton.setPressedFunc([&] { save(); delete this; }); mSaveButton.setPressedFunc([&] { save(); delete this; });
@ -48,12 +40,26 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
//initialize metadata list //initialize metadata list
addChild(&mList); addChild(&mList);
populateList(mdd); 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() 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) void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
@ -71,11 +77,11 @@ void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
int y = 0; int y = 0;
//delete button
mList.setEntry(Vector2i(0, y), Vector2i(1, 1), &mDeleteButton, true, ComponentListComponent::AlignCenter);
//fetch button //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++; y++;
@ -87,7 +93,7 @@ void GuiMetaDataEd::populateList(const std::vector<MetaDataDecl>& mdd)
mLabels.push_back(label); mLabels.push_back(label);
GuiComponent* ed = MetaDataList::makeEditor(mWindow, iter->type); 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)); ed->setValue(mMetaData->get(iter->key));
mList.setEntry(Vector2i(1, y), Vector2i(1, 1), ed, true, ComponentListComponent::AlignRight); mList.setEntry(Vector2i(1, y), Vector2i(1, 1), ed, true, ComponentListComponent::AlignRight);
mEditors.push_back(ed); mEditors.push_back(ed);
@ -112,11 +118,16 @@ void GuiMetaDataEd::save()
void GuiMetaDataEd::fetch() 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: private:
void save(); void save();
void fetch(); void fetch();
void fetchDone(std::vector<MetaDataList> results); void fetchDone(MetaDataList result);
void populateList(const std::vector<MetaDataDecl>& mdd); void populateList(const std::vector<MetaDataDecl>& mdd);
@ -35,6 +35,7 @@ private:
std::vector<TextComponent*> mLabels; std::vector<TextComponent*> mLabels;
std::vector<GuiComponent*> mEditors; std::vector<GuiComponent*> mEditors;
std::vector<MetaDataDecl> mMetaDataDecl;
MetaDataList* mMetaData; MetaDataList* mMetaData;
std::function<void()> mSavedCallback; std::function<void()> mSavedCallback;
std::function<void()> mDeleteFunc; std::function<void()> mDeleteFunc;

View file

@ -101,7 +101,7 @@ void TextComponent::onTextChanged()
calculateExtent(); calculateExtent();
std::shared_ptr<Font> f = getFont(); 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) void TextComponent::setValue(const std::string& value)

View file

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

View file

@ -1,5 +1,6 @@
#include "GamesDBScraper.h" #include "GamesDBScraper.h"
#include "../components/AsyncReqComponent.h" #include "../components/AsyncReqComponent.h"
#include "../Log.h"
std::vector<MetaDataList> GamesDBScraper::getResults(ScraperSearchParams params) std::vector<MetaDataList> GamesDBScraper::getResults(ScraperSearchParams params)
{ {
@ -18,6 +19,16 @@ std::vector<MetaDataList> GamesDBScraper::parseReq(ScraperSearchParams params, s
{ {
std::vector<MetaDataList> mdl; 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; return mdl;
} }
@ -34,4 +45,3 @@ void GamesDBScraper::getResultsAsync(ScraperSearchParams params, Window* window,
window->pushGui(req); window->pushGui(req);
} }