You can now choose a scraper in the Settings menu.

This commit is contained in:
Aloshi 2013-10-05 21:56:06 -05:00
parent 63d8908061
commit 5d6192613c
9 changed files with 157 additions and 62 deletions

View file

@ -138,7 +138,7 @@ int run_scraper_cmdline()
out << "Alright, let's do this thing!\n";
out << "=============================\n";
Scraper* scraper = Settings::getInstance()->getScraper();
std::shared_ptr<Scraper> scraper = Settings::getInstance()->getScraper();
for(auto sysIt = systems.begin(); sysIt != systems.end(); sysIt++)
{
std::vector<FileData*> files = (*sysIt)->getRootFolder()->getFilesRecursive(true);

View file

@ -4,11 +4,10 @@
#include "platform.h"
#include <boost/filesystem.hpp>
#include "scrapers/GamesDBScraper.h"
#include "scrapers/TheArchiveScraper.h"
Settings* Settings::sInstance = NULL;
Settings::Settings() : mScraper(NULL)
Settings::Settings()
{
setDefaults();
loadFile();
@ -41,10 +40,7 @@ void Settings::setDefaults()
mIntMap["GameListSortIndex"] = 0;
if(mScraper)
delete mScraper;
mScraper = new GamesDBScraper(); //TODO
mScraper = std::shared_ptr<Scraper>(new GamesDBScraper());
}
template <typename K, typename V>
@ -68,6 +64,9 @@ void Settings::saveFile()
saveMap<std::string, int>(doc, mIntMap, "int");
saveMap<std::string, float>(doc, mFloatMap, "float");
pugi::xml_node scraperNode = doc.append_child("scraper");
scraperNode.append_attribute("value").set_value(mScraper->getName());
doc.save_file(path.c_str());
}
@ -92,13 +91,25 @@ void Settings::loadFile()
setInt(node.attribute("name").as_string(), node.attribute("value").as_int());
for(pugi::xml_node node = doc.child("float"); node; node = node.next_sibling())
setFloat(node.attribute("name").as_string(), node.attribute("value").as_float());
if(doc.child("scraper"))
{
std::shared_ptr<Scraper> scr = createScraperByName(doc.child("scraper").attribute("value").as_string());
if(scr)
mScraper = scr;
}
}
Scraper* Settings::getScraper()
std::shared_ptr<Scraper> Settings::getScraper()
{
return mScraper;
}
void Settings::setScraper(std::shared_ptr<Scraper> scraper)
{
mScraper = scraper;
}
//Print a warning message if the setting we're trying to get doesn't already exist in the map, then return the value in the map.
#define SETTINGS_GETSET(type, mapName, getMethodName, setMethodName) type Settings::getMethodName(const std::string& name) \
{ \

View file

@ -23,7 +23,8 @@ public:
void setInt(const std::string& name, int value);
void setFloat(const std::string& name, float value);
Scraper* getScraper();
std::shared_ptr<Scraper> getScraper();
void setScraper(std::shared_ptr<Scraper> scraper);
private:
static Settings* sInstance;
@ -35,7 +36,7 @@ private:
std::map<std::string, bool> mBoolMap;
std::map<std::string, int> mIntMap;
std::map<std::string, float> mFloatMap;
Scraper* mScraper;
std::shared_ptr<Scraper> mScraper;
};
#endif

View file

@ -419,6 +419,18 @@ void ComponentListComponent::update(int deltaTime)
void ComponentListComponent::render(const Eigen::Affine3f& parentTrans)
{
Eigen::Affine3f trans = parentTrans * getTransform();
//draw cursor
if(cursorValid())
{
ComponentEntry* entry = getCell(mCursor.x(), mCursor.y());
Eigen::Affine3f entryTrans = trans * entry->component->getTransform();
Renderer::setMatrix(entryTrans);
Renderer::drawRect(0, 0, 4, 4, 0xFF0000FF);
Renderer::drawRect(0, 0, (int)entry->component->getSize().x(), (int)entry->component->getSize().y(), 0x0000AA22);
}
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
{
(*iter)->component->render(trans);
@ -444,16 +456,7 @@ void ComponentListComponent::render(const Eigen::Affine3f& parentTrans)
pos[0] += getColumnWidth(x);
}*/
//draw cursor
if(cursorValid())
{
ComponentEntry* entry = getCell(mCursor.x(), mCursor.y());
Eigen::Affine3f entryTrans = trans * entry->component->getTransform();
Renderer::setMatrix(entryTrans);
Renderer::drawRect(0, 0, 4, 4, 0xFF0000FF);
Renderer::drawRect(0, 0, (int)entry->component->getSize().x(), (int)entry->component->getSize().y(), 0x0000AA22);
}
}
void ComponentListComponent::textInput(const char* text)

View file

@ -65,7 +65,7 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
scrapers.push_back(std::shared_ptr<Scraper>(new GamesDBScraper()));
scrapers.push_back(std::shared_ptr<Scraper>(new TheArchiveScraper()));
mScraperOptList.populate(scrapers, [&] (const std::shared_ptr<Scraper>& s) {
return mScraperOptList.makeEntry(s->getName(), 0x00FF00FF, s);
return mScraperOptList.makeEntry(s->getName(), 0x00FF00FF, s, s->getName() == Settings::getInstance()->getScraper()->getName());
} );
mList.setEntry(Vector2i(1, 3), Vector2i(1, 1), &mScraperOptList, true, ComponentListComponent::AlignCenter);
@ -131,5 +131,8 @@ void GuiSettingsMenu::applyStates()
s->setBool("DISABLESOUNDS", mDisableSoundsSwitch.getState());
if(mScraperOptList.getSelected().size() > 0)
s->setScraper(mScraperOptList.getSelected()[0]->object);
s->saveFile();
}

View file

@ -5,7 +5,7 @@
#include <vector>
#include <functional>
#include "../Renderer.h"
#include "../Window.h"
#include "NinePatchComponent.h"
//Used to display a list of options.
//Can select one or multiple options.
@ -14,8 +14,8 @@ template<typename T>
class OptionListComponent : public GuiComponent
{
public:
OptionListComponent(Window* window) : GuiComponent(window),
mClosedCallback(nullptr), mCursor(0), mScrollOffset(0)
OptionListComponent(Window* window, bool multiSelect = false) : GuiComponent(window),
mCursor(0), mScrollOffset(0), mMultiSelect(multiSelect), mEditing(false), mBox(window, ":/textbox.png")
{
}
@ -28,11 +28,6 @@ public:
};
void setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback)
{
mClosedCallback = callback;
}
bool input(InputConfig* config, Input input)
{
if(input.value != 0)
@ -44,26 +39,32 @@ public:
}
if(config->isMappedTo("a", input))
{
select(mCursor);
if(mEditing)
{
select(mCursor);
if(!mMultiSelect)
close();
}else{
open();
}
return true;
}
if(mEntries.size() > 1)
if(mEditing && mEntries.size() > 1)
{
if(config->isMappedTo("up", input))
{
if(mCursor > 0)
{
mCursor--;
return true;
}
return true;
}
if(config->isMappedTo("down", input))
{
if(mCursor < mEntries.size() - 1)
{
mCursor++;
return true;
}
return true;
}
}
}
@ -73,33 +74,84 @@ public:
void render(const Eigen::Affine3f& parentTrans)
{
Eigen::Affine3f trans = parentTrans * getTransform();
std::shared_ptr<Font> font = getFont();
Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(), (int)trans.translation().y()),
Eigen::Vector2i((int)getSize().x(), (int)getSize().y()));
for(unsigned int i = mScrollOffset; i < mTextCaches.size(); i++)
//draw the option list
if(mEditing)
{
Eigen::Affine3f trans = parentTrans * getTransform();
unsigned int renderCount = mTextCaches.size() - mScrollOffset;
float height = (float)renderCount * font->getHeight();
trans.translate(Eigen::Vector3f(0, -height / 2 + font->getHeight() * 0.5f, 0));
mBox.fitTo(Eigen::Vector2f(mSize.x(), height));
mBox.render(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0, 0, (int)getSize().x(), (int)height, 0xFFFFFFFF);
if(i == mCursor)
Renderer::drawRect(0, 0, (int)mSize.x(), font->getHeight(), 0x000000FF);
for(unsigned int i = mScrollOffset; i < renderCount; i++)
{
Renderer::setMatrix(trans);
font->renderTextCache(mTextCaches.at(i));
trans = trans.translate(Eigen::Vector3f(0, (float)font->getHeight(), 0));
char rectOpacity = 0x00;
if(i == mCursor)
rectOpacity += 0x22;
if(mEntries.at(i).selected)
rectOpacity += 0x44;
Renderer::drawRect(0, 0, (int)mSize.x(), font->getHeight(), 0x00000000 | rectOpacity);
Renderer::setMatrix(trans);
font->renderTextCache(mTextCaches.at(i));
trans = trans.translate(Eigen::Vector3f(0, (float)font->getHeight(), 0));
}
}else{
Renderer::setMatrix(parentTrans * getTransform());
unsigned int color = 0x000000FF;
if(mMultiSelect)
{
//draw "# selected"
unsigned int selectedCount = 0;
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
{
if(it->selected)
selectedCount++;
}
std::stringstream ss;
ss << selectedCount << " selected";
font->drawText(ss.str(), Eigen::Vector2f(0, 0), color);
}else{
//draw selected option
bool found = false;
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
{
if(it->selected)
{
font->drawText(it->text, Eigen::Vector2f(0, 0), color);
found = true;
break;
}
}
if(!found)
font->drawText("Not set", Eigen::Vector2f(0, 0), color);
}
}
Renderer::popClipRect();
trans = parentTrans * getTransform();
renderChildren(trans);
renderChildren(parentTrans * getTransform());
}
ListEntry makeEntry(const std::string& name, unsigned int color, T obj) const
ListEntry makeEntry(const std::string& name, unsigned int color, T obj, bool selected = false) const
{
ListEntry e = {name, color, false, obj};
ListEntry e = {name, color, selected, obj};
return e;
}
@ -138,14 +190,22 @@ private:
if(i >= mEntries.size())
return;
if(!mMultiSelect)
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
it->selected = false;
mEntries.at(i).selected = !mEntries.at(i).selected;
updateTextCaches();
}
void close()
{
if(mClosedCallback)
mClosedCallback(getSelected());
mEditing = false;
}
void open()
{
mEditing = true;
}
void updateTextCaches()
@ -159,7 +219,7 @@ private:
TextCache* cache;
std::shared_ptr<Font> font = getFont();
Eigen::Vector2f newSize = getSize();
newSize[1] = 0;
newSize[1] = (float)font->getHeight();
for(unsigned int i = 0; i < mEntries.size(); i++)
{
cache = font->buildTextCache(mEntries.at(i).text, 0, 0, mEntries.at(i).color);
@ -167,23 +227,24 @@ private:
if(cache->metrics.size.x() > newSize.x())
newSize[0] = cache->metrics.size.x();
newSize[1] += cache->metrics.size.y();
}
setSize(newSize);
}
std::shared_ptr<Font> getFont()
{
return Font::get(FONT_SIZE_SMALL);
return Font::get(FONT_SIZE_MEDIUM);
}
std::function<void(std::vector<const ListEntry*>)> mClosedCallback;
unsigned int mCursor;
unsigned int mScrollOffset;
bool mMultiSelect;
bool mEditing;
NinePatchComponent mBox;
std::vector<ListEntry> mEntries;
std::vector<TextCache*> mTextCaches;
};

View file

@ -6,6 +6,9 @@
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>
#include "GamesDBScraper.h"
#include "TheArchiveScraper.h"
std::vector<MetaDataList> Scraper::getResults(ScraperSearchParams params)
{
std::shared_ptr<HttpReq> req = makeHttpReq(params);
@ -157,3 +160,14 @@ std::string getSaveAsPath(const std::string& subdirectory, const std::string& na
path += name + ext;
return path;
}
std::shared_ptr<Scraper> createScraperByName(const std::string& name)
{
if(name == "TheGamesDB")
return std::shared_ptr<Scraper>(new GamesDBScraper());
else if(name == "TheArchive")
return std::shared_ptr<Scraper>(new TheArchiveScraper());
return nullptr;
}

View file

@ -30,6 +30,8 @@ private:
virtual std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) = 0;
};
std::shared_ptr<Scraper> createScraperByName(const std::string& name);
//About the same as "~/.emulationstation/downloaded_images/[subdirectory]/[name].[url's extension]".
//Will create the "downloaded_images" and "subdirectory" directories if they do not exist.
std::string getSaveAsPath(const std::string& subdirectory, const std::string& name, const std::string& url);

View file

@ -4,7 +4,7 @@
#include "../Log.h"
#include "../pugiXML/pugixml.hpp"
const char* TheArchiveScraper::getName() { return "TheArchiveVG"; }
const char* TheArchiveScraper::getName() { return "TheArchive"; }
std::shared_ptr<HttpReq> TheArchiveScraper::makeHttpReq(ScraperSearchParams params)
{