mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 07:35: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/ImageComponent.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/ScrollableContainer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.cpp
|
||||
|
|
|
@ -3,13 +3,17 @@
|
|||
#include "../Settings.h"
|
||||
#include "../VolumeControl.h"
|
||||
|
||||
#include "../scrapers/TheArchiveScraper.h"
|
||||
#include "../scrapers/GamesDBScraper.h"
|
||||
|
||||
GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||
mList(window, Eigen::Vector2i(2, 4)),
|
||||
mList(window, Eigen::Vector2i(2, 5)),
|
||||
mBox(mWindow, ":/frame.png", 0x444444FF),
|
||||
mDrawFramerateSwitch(window),
|
||||
mVolumeSlider(window, 0, 100, 1),
|
||||
mDisableSoundsSwitch(window, false),
|
||||
mSaveLabel(window)
|
||||
mSaveLabel(window),
|
||||
mScraperOptList(window)
|
||||
{
|
||||
loadStates();
|
||||
|
||||
|
@ -20,6 +24,7 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
|||
|
||||
using namespace Eigen;
|
||||
|
||||
//drawFramerate label
|
||||
TextComponent* label = new TextComponent(mWindow);
|
||||
label->setText("Draw Framerate: ");
|
||||
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));
|
||||
|
||||
//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
|
||||
mSaveLabel.setText("SAVE");
|
||||
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
|
||||
mList.setPosition(Renderer::getScreenWidth() / 2 - mList.getSize().x() / 2, Renderer::getScreenHeight() / 2 - mList.getSize().y() / 2);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "SliderComponent.h"
|
||||
#include "TextComponent.h"
|
||||
#include "NinePatchComponent.h"
|
||||
#include "OptionListComponent.h"
|
||||
#include "../scrapers/Scraper.h"
|
||||
|
||||
class GuiSettingsMenu : public GuiComponent
|
||||
{
|
||||
|
@ -28,6 +30,7 @@ private:
|
|||
SwitchComponent mDrawFramerateSwitch;
|
||||
SliderComponent mVolumeSlider;
|
||||
SwitchComponent mDisableSoundsSwitch;
|
||||
OptionListComponent< std::shared_ptr<Scraper> > mScraperOptList;
|
||||
TextComponent mSaveLabel;
|
||||
|
||||
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
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
#include "../Font.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "../Renderer.h"
|
||||
#include "../Window.h"
|
||||
|
||||
//Used to display a list of options.
|
||||
//Can select one or multiple options.
|
||||
|
||||
struct ListEntry
|
||||
{
|
||||
std::string name;
|
||||
unsigned int color;
|
||||
bool selected;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class OptionListComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
OptionListComponent(Window* window);
|
||||
OptionListComponent(Window* window) : GuiComponent(window),
|
||||
mClosedCallback(nullptr), mCursor(0), mScrollOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool input(InputConfig* config, Input input);
|
||||
void render(const Eigen::Affine3f& trans);
|
||||
struct ListEntry
|
||||
{
|
||||
std::string text;
|
||||
unsigned int color;
|
||||
bool selected;
|
||||
T object;
|
||||
};
|
||||
|
||||
void setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback);
|
||||
|
||||
template<typename T>
|
||||
void populate(const std::vector<T>& vec, std::function<ListEntry(const T&)> selector);
|
||||
void setClosedCallback(std::function<void(std::vector<const ListEntry*>)> callback)
|
||||
{
|
||||
mClosedCallback = callback;
|
||||
}
|
||||
|
||||
std::vector<const ListEntry*> getSelected();
|
||||
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 close();
|
||||
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 "../MetaData.h"
|
||||
|
||||
const char* GamesDBScraper::getName() { return "TheGamesDB"; }
|
||||
|
||||
std::shared_ptr<HttpReq> GamesDBScraper::makeHttpReq(ScraperSearchParams params)
|
||||
{
|
||||
std::string path = "/api/GetGame.php?";
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
class GamesDBScraper : public Scraper
|
||||
{
|
||||
public:
|
||||
const char* getName();
|
||||
private:
|
||||
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) 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 void getResultsAsync(ScraperSearchParams params, Window* window, std::function<void(std::vector<MetaDataList>)> returnFunc);
|
||||
|
||||
virtual const char* getName() = 0;
|
||||
private:
|
||||
virtual std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) = 0;
|
||||
virtual std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "../Log.h"
|
||||
#include "../pugiXML/pugixml.hpp"
|
||||
|
||||
const char* TheArchiveScraper::getName() { return "TheArchiveVG"; }
|
||||
|
||||
std::shared_ptr<HttpReq> TheArchiveScraper::makeHttpReq(ScraperSearchParams params)
|
||||
{
|
||||
std::string path = "/2.0/Archive.search/xml/7TTRM4MNTIKR2NNAGASURHJOZJ3QXQC5/";
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
class TheArchiveScraper : public Scraper
|
||||
{
|
||||
public:
|
||||
const char* getName();
|
||||
private:
|
||||
std::shared_ptr<HttpReq> makeHttpReq(ScraperSearchParams params) override;
|
||||
std::vector<MetaDataList> parseReq(ScraperSearchParams params, std::shared_ptr<HttpReq>) override;
|
||||
|
|
Loading…
Reference in a new issue