mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-24 23:25:38 +00:00
Work on scraper UI integration (about there, just need a real scraper
now).
This commit is contained in:
parent
5dfaeeabb4
commit
3105073e50
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -334,3 +334,8 @@ bool SystemData::hasGamelist()
|
|||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<MetaDataDecl> SystemData::getGameMDD()
|
||||
{
|
||||
return MetaDataList::getDefaultGameMDD();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(); }
|
||||
));
|
||||
|
|
168
src/components/GuiGameScraper.cpp
Normal file
168
src/components/GuiGameScraper.cpp
Normal 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;
|
||||
}
|
44
src/components/GuiGameScraper.h
Normal file
44
src/components/GuiGameScraper.h
Normal 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;
|
||||
};
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue