mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
OptionListComponent
This commit is contained in:
parent
6956211ff0
commit
a4185176da
|
@ -221,7 +221,6 @@ set(ES_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/OptionListComponent.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.cpp
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
#include "../Settings.h"
|
#include "../Settings.h"
|
||||||
#include "../VolumeControl.h"
|
#include "../VolumeControl.h"
|
||||||
|
|
||||||
|
#include "../scrapers/TheArchiveScraper.h"
|
||||||
|
#include "../scrapers/GamesDBScraper.h"
|
||||||
|
|
||||||
GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||||
mList(window, Eigen::Vector2i(2, 4)),
|
mList(window, Eigen::Vector2i(2, 5)),
|
||||||
mBox(mWindow, ":/frame.png", 0x444444FF),
|
mBox(mWindow, ":/frame.png", 0x444444FF),
|
||||||
mDrawFramerateSwitch(window),
|
mDrawFramerateSwitch(window),
|
||||||
mVolumeSlider(window, 0, 100, 1),
|
mVolumeSlider(window, 0, 100, 1),
|
||||||
mDisableSoundsSwitch(window, false),
|
mDisableSoundsSwitch(window, false),
|
||||||
mSaveLabel(window)
|
mSaveLabel(window),
|
||||||
|
mScraperOptList(window)
|
||||||
{
|
{
|
||||||
loadStates();
|
loadStates();
|
||||||
|
|
||||||
|
@ -20,6 +24,7 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||||
|
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
|
|
||||||
|
//drawFramerate label
|
||||||
TextComponent* label = new TextComponent(mWindow);
|
TextComponent* label = new TextComponent(mWindow);
|
||||||
label->setText("Draw Framerate: ");
|
label->setText("Draw Framerate: ");
|
||||||
label->setColor(0x0000FFFF);
|
label->setColor(0x0000FFFF);
|
||||||
|
@ -48,11 +53,27 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||||
|
|
||||||
mList.setEntry(Vector2i(1, 2), Vector2i(1, 1), &mDisableSoundsSwitch, true, ComponentListComponent::AlignCenter, Matrix<bool, 1, 2>(true, true));
|
mList.setEntry(Vector2i(1, 2), Vector2i(1, 1), &mDisableSoundsSwitch, true, ComponentListComponent::AlignCenter, Matrix<bool, 1, 2>(true, true));
|
||||||
|
|
||||||
|
//scraper label
|
||||||
|
label = new TextComponent(mWindow);
|
||||||
|
label->setText("Scraper: ");
|
||||||
|
label->setColor(0x0000FFFF);
|
||||||
|
mLabels.push_back(label);
|
||||||
|
mList.setEntry(Vector2i(0, 3), Vector2i(1, 1), label, false, ComponentListComponent::AlignRight);
|
||||||
|
|
||||||
|
//fill scraper list
|
||||||
|
std::vector< std::shared_ptr<Scraper> > scrapers;
|
||||||
|
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);
|
||||||
|
} );
|
||||||
|
|
||||||
|
mList.setEntry(Vector2i(1, 3), Vector2i(1, 1), &mScraperOptList, true, ComponentListComponent::AlignCenter);
|
||||||
|
|
||||||
//save label
|
//save label
|
||||||
mSaveLabel.setText("SAVE");
|
mSaveLabel.setText("SAVE");
|
||||||
mSaveLabel.setColor(0x000000FF);
|
mSaveLabel.setColor(0x000000FF);
|
||||||
mList.setEntry(Vector2i(0, 3), Vector2i(2, 1), &mSaveLabel, true, ComponentListComponent::AlignCenter, Matrix<bool, 1, 2>(false, true));
|
mList.setEntry(Vector2i(0, 4), Vector2i(2, 1), &mSaveLabel, true, ComponentListComponent::AlignCenter, Matrix<bool, 1, 2>(false, true));
|
||||||
|
|
||||||
//center list
|
//center list
|
||||||
mList.setPosition(Renderer::getScreenWidth() / 2 - mList.getSize().x() / 2, Renderer::getScreenHeight() / 2 - mList.getSize().y() / 2);
|
mList.setPosition(Renderer::getScreenWidth() / 2 - mList.getSize().x() / 2, Renderer::getScreenHeight() / 2 - mList.getSize().y() / 2);
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "SliderComponent.h"
|
#include "SliderComponent.h"
|
||||||
#include "TextComponent.h"
|
#include "TextComponent.h"
|
||||||
#include "NinePatchComponent.h"
|
#include "NinePatchComponent.h"
|
||||||
|
#include "OptionListComponent.h"
|
||||||
|
#include "../scrapers/Scraper.h"
|
||||||
|
|
||||||
class GuiSettingsMenu : public GuiComponent
|
class GuiSettingsMenu : public GuiComponent
|
||||||
{
|
{
|
||||||
|
@ -28,6 +30,7 @@ private:
|
||||||
SwitchComponent mDrawFramerateSwitch;
|
SwitchComponent mDrawFramerateSwitch;
|
||||||
SliderComponent mVolumeSlider;
|
SliderComponent mVolumeSlider;
|
||||||
SwitchComponent mDisableSoundsSwitch;
|
SwitchComponent mDisableSoundsSwitch;
|
||||||
|
OptionListComponent< std::shared_ptr<Scraper> > mScraperOptList;
|
||||||
TextComponent mSaveLabel;
|
TextComponent mSaveLabel;
|
||||||
|
|
||||||
std::vector<GuiComponent*> mLabels;
|
std::vector<GuiComponent*> mLabels;
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include "OptionListComponent.h"
|
|
||||||
|
|
||||||
OptionListComponent::OptionListComponent(Window* window) : GuiComponent(window),
|
|
||||||
mClosedCallback(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionListComponent::setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback)
|
|
||||||
{
|
|
||||||
mClosedCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OptionListComponent::input(InputConfig* config, Input input)
|
|
||||||
{
|
|
||||||
return GuiComponent::input(config, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionListComponent::render(const Eigen::Affine3f& parentTrans)
|
|
||||||
{
|
|
||||||
Eigen::Affine3f trans = parentTrans * getTransform();
|
|
||||||
|
|
||||||
renderChildren(trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void OptionListComponent::populate(const std::vector<T>& vec, std::function<ListEntry(const T&)> selector)
|
|
||||||
{
|
|
||||||
for(auto it = vec.begin(); it != vec.end(); it++)
|
|
||||||
{
|
|
||||||
ListEntry e = selector(*it);
|
|
||||||
if(!e.name.empty())
|
|
||||||
mEntries.push_back(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const ListEntry*> OptionListComponent::getSelected()
|
|
||||||
{
|
|
||||||
std::vector<const ListEntry*> ret;
|
|
||||||
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
|
||||||
{
|
|
||||||
if((*it).selected)
|
|
||||||
ret.push_back(&(*it));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionListComponent::close()
|
|
||||||
{
|
|
||||||
if(mClosedCallback)
|
|
||||||
mClosedCallback(getSelected());
|
|
||||||
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,38 +1,189 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../GuiComponent.h"
|
#include "../GuiComponent.h"
|
||||||
|
#include "../Font.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "../Renderer.h"
|
||||||
|
#include "../Window.h"
|
||||||
|
|
||||||
//Used to display a list of options.
|
//Used to display a list of options.
|
||||||
//Can select one or multiple options.
|
//Can select one or multiple options.
|
||||||
|
|
||||||
struct ListEntry
|
template<typename T>
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
unsigned int color;
|
|
||||||
bool selected;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OptionListComponent : public GuiComponent
|
class OptionListComponent : public GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OptionListComponent(Window* window);
|
OptionListComponent(Window* window) : GuiComponent(window),
|
||||||
|
mClosedCallback(nullptr), mCursor(0), mScrollOffset(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool input(InputConfig* config, Input input);
|
struct ListEntry
|
||||||
void render(const Eigen::Affine3f& trans);
|
{
|
||||||
|
std::string text;
|
||||||
void setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback);
|
unsigned int color;
|
||||||
|
bool selected;
|
||||||
template<typename T>
|
T object;
|
||||||
void populate(const std::vector<T>& vec, std::function<ListEntry(const T&)> selector);
|
};
|
||||||
|
|
||||||
std::vector<const ListEntry*> getSelected();
|
|
||||||
private:
|
void setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback)
|
||||||
void close();
|
{
|
||||||
|
mClosedCallback = callback;
|
||||||
std::function<void(std::vector<const ListEntry*>)> mClosedCallback;
|
}
|
||||||
|
|
||||||
std::vector<ListEntry> mEntries;
|
bool input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
|
if(input.value != 0)
|
||||||
|
{
|
||||||
|
if(config->isMappedTo("b", input))
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(config->isMappedTo("a", input))
|
||||||
|
{
|
||||||
|
select(mCursor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(mEntries.size() > 1)
|
||||||
|
{
|
||||||
|
if(config->isMappedTo("up", input))
|
||||||
|
{
|
||||||
|
if(mCursor > 0)
|
||||||
|
{
|
||||||
|
mCursor--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(config->isMappedTo("down", input))
|
||||||
|
{
|
||||||
|
if(mCursor < mEntries.size() - 1)
|
||||||
|
{
|
||||||
|
mCursor++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GuiComponent::input(config, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
Renderer::setMatrix(trans);
|
||||||
|
|
||||||
|
if(i == mCursor)
|
||||||
|
Renderer::drawRect(0, 0, (int)mSize.x(), font->getHeight(), 0x000000FF);
|
||||||
|
|
||||||
|
font->renderTextCache(mTextCaches.at(i));
|
||||||
|
trans = trans.translate(Eigen::Vector3f(0, (float)font->getHeight(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::popClipRect();
|
||||||
|
|
||||||
|
trans = parentTrans * getTransform();
|
||||||
|
renderChildren(trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListEntry makeEntry(const std::string& name, unsigned int color, T obj) const
|
||||||
|
{
|
||||||
|
ListEntry e = {name, color, false, obj};
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void populate(std::vector<T>& vec, std::function<ListEntry(const T&)> selector)
|
||||||
|
{
|
||||||
|
for(auto it = vec.begin(); it != vec.end(); it++)
|
||||||
|
{
|
||||||
|
ListEntry e = selector(*it);
|
||||||
|
if(!e.text.empty())
|
||||||
|
mEntries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTextCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEntry(ListEntry e)
|
||||||
|
{
|
||||||
|
mEntries.push_back(e);
|
||||||
|
updateTextCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const ListEntry*> getSelected()
|
||||||
|
{
|
||||||
|
std::vector<const ListEntry*> ret;
|
||||||
|
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||||
|
{
|
||||||
|
if((*it).selected)
|
||||||
|
ret.push_back(&(*it));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void select(unsigned int i)
|
||||||
|
{
|
||||||
|
if(i >= mEntries.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mEntries.at(i).selected = !mEntries.at(i).selected;
|
||||||
|
updateTextCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if(mClosedCallback)
|
||||||
|
mClosedCallback(getSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateTextCaches()
|
||||||
|
{
|
||||||
|
for(auto it = mTextCaches.begin(); it != mTextCaches.end(); it++)
|
||||||
|
{
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
mTextCaches.clear();
|
||||||
|
|
||||||
|
TextCache* cache;
|
||||||
|
std::shared_ptr<Font> font = getFont();
|
||||||
|
Eigen::Vector2f newSize = getSize();
|
||||||
|
newSize[1] = 0;
|
||||||
|
for(unsigned int i = 0; i < mEntries.size(); i++)
|
||||||
|
{
|
||||||
|
cache = font->buildTextCache(mEntries.at(i).text, 0, 0, mEntries.at(i).color);
|
||||||
|
mTextCaches.push_back(cache);
|
||||||
|
|
||||||
|
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(*mWindow->getResourceManager(), Font::getDefaultPath(), FONT_SIZE_SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::function<void(std::vector<const ListEntry*>)> mClosedCallback;
|
||||||
|
unsigned int mCursor;
|
||||||
|
unsigned int mScrollOffset;
|
||||||
|
|
||||||
|
std::vector<ListEntry> mEntries;
|
||||||
|
std::vector<TextCache*> mTextCaches;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "../pugiXML/pugixml.hpp"
|
#include "../pugiXML/pugixml.hpp"
|
||||||
#include "../MetaData.h"
|
#include "../MetaData.h"
|
||||||
|
|
||||||
|
const char* GamesDBScraper::getName() { return "TheGamesDB"; }
|
||||||
|
|
||||||
std::shared_ptr<HttpReq> GamesDBScraper::makeHttpReq(ScraperSearchParams params)
|
std::shared_ptr<HttpReq> GamesDBScraper::makeHttpReq(ScraperSearchParams params)
|
||||||
{
|
{
|
||||||
std::string path = "/api/GetGame.php?";
|
std::string path = "/api/GetGame.php?";
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
class GamesDBScraper : public Scraper
|
class GamesDBScraper : public Scraper
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
const char* getName();
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) override;
|
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) override;
|
||||||
std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) override;
|
std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) override;
|
||||||
|
|
|
@ -24,7 +24,9 @@ public:
|
||||||
virtual std::vector<MetaDataList> getResults(ScraperSearchParams params);
|
virtual std::vector<MetaDataList> getResults(ScraperSearchParams params);
|
||||||
virtual void getResultsAsync(ScraperSearchParams params, Window* window, std::function<void(std::vector<MetaDataList>)> returnFunc);
|
virtual void getResultsAsync(ScraperSearchParams params, Window* window, std::function<void(std::vector<MetaDataList>)> returnFunc);
|
||||||
|
|
||||||
|
virtual const char* getName() = 0;
|
||||||
private:
|
private:
|
||||||
virtual std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) = 0;
|
virtual std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) = 0;
|
||||||
virtual std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) = 0;
|
virtual std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "../Log.h"
|
#include "../Log.h"
|
||||||
#include "../pugiXML/pugixml.hpp"
|
#include "../pugiXML/pugixml.hpp"
|
||||||
|
|
||||||
|
const char* TheArchiveScraper::getName() { return "TheArchiveVG"; }
|
||||||
|
|
||||||
std::shared_ptr<HttpReq> TheArchiveScraper::makeHttpReq(ScraperSearchParams params)
|
std::shared_ptr<HttpReq> TheArchiveScraper::makeHttpReq(ScraperSearchParams params)
|
||||||
{
|
{
|
||||||
std::string path = "/2.0/Archive.search/xml/7TTRM4MNTIKR2NNAGASURHJOZJ3QXQC5/";
|
std::string path = "/2.0/Archive.search/xml/7TTRM4MNTIKR2NNAGASURHJOZJ3QXQC5/";
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
class TheArchiveScraper : public Scraper
|
class TheArchiveScraper : public Scraper
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
const char* getName();
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) override;
|
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) override;
|
||||||
std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) override;
|
std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) override;
|
||||||
|
|
Loading…
Reference in a new issue