From d0dfe480faaccaef6d0b5a27dd5ddf5401902b91 Mon Sep 17 00:00:00 2001 From: Aloshi Date: Wed, 5 Mar 2014 19:49:32 -0600 Subject: [PATCH] Work on new OptionListComponent. --- src/components/ComponentList.cpp | 3 + src/components/OptionListComponent.h | 402 ++++++++------------------- src/guis/GuiScraperStart.cpp | 14 +- src/guis/GuiSettingsMenu.cpp | 10 +- 4 files changed, 135 insertions(+), 294 deletions(-) diff --git a/src/components/ComponentList.cpp b/src/components/ComponentList.cpp index 2f8db2a1d..e1a364206 100644 --- a/src/components/ComponentList.cpp +++ b/src/components/ComponentList.cpp @@ -104,6 +104,9 @@ void ComponentList::onCursorChanged(const CursorState& state) void ComponentList::render(const Eigen::Affine3f& parentTrans) { + if(!size()) + return; + Eigen::Affine3f trans = parentTrans * getTransform(); // clip everything to be inside our bounds diff --git a/src/components/OptionListComponent.h b/src/components/OptionListComponent.h index f81d248ea..4fc964287 100644 --- a/src/components/OptionListComponent.h +++ b/src/components/OptionListComponent.h @@ -2,35 +2,90 @@ #include "../GuiComponent.h" #include "../resources/Font.h" -#include -#include #include "../Renderer.h" -#include "NinePatchComponent.h" #include "../Window.h" +#include "TextComponent.h" +#include "MenuComponent.h" +#include //Used to display a list of options. //Can select one or multiple options. +// if !multiSelect +// * <- curEntry -> + +// always +// * press a -> open full list + template class OptionListComponent : public GuiComponent { -public: - OptionListComponent(Window* window, bool multiSelect = false) : GuiComponent(window), - mMultiSelect(multiSelect) +private: + struct OptionListData { - if(multiSelect) - setSize(getFont()->sizeText("0 selected")); - else - setSize(getFont()->sizeText("Not set")); - } - - struct ListEntry - { - std::string text; - bool selected; + std::string name; T object; + bool selected; }; + class OptionListPopup : public GuiComponent + { + private: + MenuComponent mMenu; + OptionListComponent* mParent; + + public: + OptionListPopup(Window* window, OptionListComponent* parent) : GuiComponent(window), + mMenu(window, "optionlist"), mParent(parent) + { + auto font = Font::get(FONT_SIZE_MEDIUM); + ComponentListRow row; + for(auto it = mParent->mEntries.begin(); it != mParent->mEntries.end(); it++) + { + row.elements.clear(); + row.addElement(std::make_shared(mWindow, it->name, font, 0x777777FF), true); + + mMenu.addRow(row); + } + + mMenu.setPosition((Renderer::getScreenWidth() - mMenu.getSize().x()) / 2, (Renderer::getScreenHeight() - mMenu.getSize().y()) / 2); + addChild(&mMenu); + } + + bool input(InputConfig* config, Input input) override + { + if(config->isMappedTo("b", input) && input.value != 0) + { + delete this; + return true; + } + + return GuiComponent::input(config, input); + } + + virtual ~OptionListPopup() + { + // commit changes + + } + }; + +public: + OptionListComponent(Window* window, bool multiSelect = false) : GuiComponent(window), mText(window), mMultiSelect(multiSelect) + { + auto font = Font::get(FONT_SIZE_MEDIUM); + mText.setFont(font); + mText.setColor(0x777777FF); + mText.setCentered(true); + addChild(&mText); + + setSize(Renderer::getScreenWidth() * 0.2f, (float)font->getHeight()); + } + + void onSizeChanged() override + { + mText.setSize(mSize); + } bool input(InputConfig* config, Input input) override { @@ -41,90 +96,18 @@ public: open(); return true; } - } - return GuiComponent::input(config, input); - } - - void render(const Eigen::Affine3f& parentTrans) - { - std::shared_ptr font = getFont(); - - 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(!mMultiSelect) { - 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) + if(config->isMappedTo("left", input)) { - font->drawText(it->text, Eigen::Vector2f(0, 0), color); - found = true; - break; + // move selection to previous + }else if(config->isMappedTo("right", input)) + { + // move selection to next } } - - if(!found) - font->drawText("Not set", Eigen::Vector2f(0, 0), color); } - - renderChildren(parentTrans * getTransform()); - } - - ListEntry makeEntry(const std::string& name, T obj, bool selected = false) const - { - ListEntry e; - e.text = name; - e.object = obj; - e.selected = selected; - return e; - } - - void populate(std::vector& vec, std::function selector) - { - for(auto it = vec.begin(); it != vec.end(); it++) - { - ListEntry e = selector(*it); - if(!e.text.empty()) - addEntry(e); - } - } - - void addEntry(ListEntry e) - { - mEntries.push_back(e); - - Eigen::Vector2f size = getFont()->sizeText(e.text); - if(size.x() > mSize.x()) - setSize(size.x(), mSize.y()); - } - - std::vector getSelected() - { - std::vector ret; - for(auto it = mEntries.begin(); it != mEntries.end(); it++) - { - if((*it).selected) - ret.push_back(&(*it)); - } - - return ret; + return GuiComponent::input(config, input); } std::vector getSelectedObjects() @@ -132,206 +115,63 @@ public: std::vector ret; for(auto it = mEntries.begin(); it != mEntries.end(); it++) { - if((*it).selected) + if(it->selected) ret.push_back(it->object); } return ret; } + T getSelected() + { + assert(mMultiSelect == false); + auto selected = getSelectedObjects(); + assert(selected.size() == 1); + return selected.at(0); + } + + void add(const std::string& name, const T& obj, bool selected) + { + OptionListData e; + e.name = name; + e.object = obj; + e.selected = selected; + + mEntries.push_back(e); + onSelectedChanged(); + } + private: void open() { - mWindow->pushGui(new OptionListPopup(mWindow, *this)); + mWindow->pushGui(new OptionListPopup(mWindow, this)); } - void select(unsigned int i) + void onSelectedChanged() { - if(i >= mEntries.size()) - return; - - if(!mMultiSelect) + if(mMultiSelect) + { + // display # selected + std::stringstream ss; + ss << getSelectedObjects().size() << " selected"; + mText.setText(ss.str()); + }else{ + // display currently selected + l/r cursors for(auto it = mEntries.begin(); it != mEntries.end(); it++) - it->selected = false; - - mEntries.at(i).selected = !mEntries.at(i).selected; + { + if(it->selected) + { + mText.setText(it->name); + break; + } + } + } } - std::shared_ptr getFont() - { - return Font::get(FONT_SIZE_MEDIUM); - } - - - class OptionListPopup : public GuiComponent - { - public: - OptionListPopup(Window* window, OptionListComponent& optList) : GuiComponent(window), - mOptList(optList), mBox(window, ":/textbox.png"), mCursor(0), mScrollOffset(0), mCursorTimer(0) - { - //find global position - GuiComponent* p = &mOptList; - do { - mPosition += p->getPosition(); - } while(p = p->getParent()); - - mSize = mOptList.getSize(); - updateTextCaches(); - } - - void render(const Eigen::Affine3f& parentTrans) override - { - Eigen::Affine3f trans = parentTrans * getTransform(); - - std::shared_ptr font = mOptList.getFont(); - - unsigned int renderCount = getPageSize(); - if(renderCount + mScrollOffset > mTextCaches.size()) - renderCount = mTextCaches.size() - mScrollOffset; - - unsigned int renderTo = mScrollOffset + renderCount; - - 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); - - for(unsigned int i = mScrollOffset; i < renderTo; i++) - { - Renderer::setMatrix(trans); - - char rectOpacity = 0x00; - if(i == mCursor) - rectOpacity += 0x22; - if(mOptList.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)); - } - } - - bool input(InputConfig* config, Input input) - { - if(input.value != 0) - { - if(config->isMappedTo("b", input)) - { - close(); - return true; - } - if(config->isMappedTo("a", input)) - { - mOptList.select(mCursor); - if(!mOptList.mMultiSelect) - close(); - - return true; - } - if(config->isMappedTo("up", input)) - { - mCursorDir = -1; - mCursorTimer = -350; - moveCursor(); - return true; - } - if(config->isMappedTo("down", input)) - { - mCursorDir = 1; - mCursorTimer = -350; - moveCursor(); - return true; - } - }else{ - if(config->isMappedTo("up", input) || config->isMappedTo("down", input)) - mCursorDir = 0; - } - - return GuiComponent::input(config, input); - } - - void update(int deltaTime) - { - if(mCursorDir != 0) - { - mCursorTimer += deltaTime; - while(mCursorTimer >= 100) - { - moveCursor(); - mCursorTimer -= 100; - } - } - } - - private: - void moveCursor() - { - if(mOptList.mEntries.size() == 0) - return; - - if(mCursorDir < 0) //scroll up - { - if(mCursor > 0) - mCursor--; - - if(mCursor < mScrollOffset) - mScrollOffset--; - }else if(mCursorDir > 0) //scroll down - { - if(mCursor < mOptList.mEntries.size() - 1) - mCursor++; - - if(mCursor - mScrollOffset >= getPageSize()) - mScrollOffset++; - } - } - - void close() - { - delete this; - } - - void updateTextCaches() - { - for(auto it = mTextCaches.begin(); it != mTextCaches.end(); it++) - { - delete *it; - } - mTextCaches.clear(); - - TextCache* cache; - std::shared_ptr font = mOptList.getFont(); - for(unsigned int i = 0; i < mOptList.mEntries.size(); i++) - { - cache = font->buildTextCache(mOptList.mEntries.at(i).text, 0, 0, 0x000000FF); - mTextCaches.push_back(cache); - } - } - - unsigned int getPageSize() - { - return 5; - } - - OptionListComponent& mOptList; - NinePatchComponent mBox; - - unsigned int mCursor; - int mCursorDir; - int mCursorTimer; - unsigned int mScrollOffset; - std::vector mTextCaches; - }; - bool mMultiSelect; - - std::vector mEntries; + + TextComponent mText; + + std::vector mEntries; }; + diff --git a/src/guis/GuiScraperStart.cpp b/src/guis/GuiScraperStart.cpp index 1eb8f4268..99b4347ad 100644 --- a/src/guis/GuiScraperStart.cpp +++ b/src/guis/GuiScraperStart.cpp @@ -23,20 +23,18 @@ GuiScraperStart::GuiScraperStart(Window* window) : GuiComponent(window), using namespace Eigen; //add filters (with first one selected) - mFiltersOpt.addEntry(mFiltersOpt.makeEntry("All Games", - [](SystemData*, FileData*) -> bool { return true; }, true)); - mFiltersOpt.addEntry(mFiltersOpt.makeEntry("Missing Image", - [](SystemData*, FileData* g) -> bool { return g->metadata.get("image").empty(); })); + mFiltersOpt.add("All Games", + [](SystemData*, FileData*) -> bool { return true; }, true); + mFiltersOpt.add("Missing Image", + [](SystemData*, FileData* g) -> bool { return g->metadata.get("image").empty(); }, false); mList.setEntry(Vector2i(0, 0), Vector2i(1, 1), &mFilterLabel, false, ComponentGrid::AlignRight); mList.setEntry(Vector2i(1, 0), Vector2i(1, 1), &mFiltersOpt, true, ComponentGrid::AlignLeft); //add systems (all with a platformid specified selected) std::vector sys = SystemData::sSystemVector; - mSystemsOpt.populate(sys, - [&](SystemData* s) { - return mSystemsOpt.makeEntry(s->getName(), s, s->getPlatformId() != PlatformIds::PLATFORM_UNKNOWN); - }); + for(auto it = sys.begin(); it != sys.end(); it++) + mSystemsOpt.add((*it)->getFullName(), *it, (*it)->getPlatformId() != PlatformIds::PLATFORM_UNKNOWN); mList.setEntry(Vector2i(0, 1), Vector2i(1, 1), &mSystemsLabel, false, ComponentGrid::AlignRight); mList.setEntry(Vector2i(1, 1), Vector2i(1, 1), &mSystemsOpt, true, ComponentGrid::AlignLeft); diff --git a/src/guis/GuiSettingsMenu.cpp b/src/guis/GuiSettingsMenu.cpp index 059f76a27..4a559e2ab 100644 --- a/src/guis/GuiSettingsMenu.cpp +++ b/src/guis/GuiSettingsMenu.cpp @@ -41,13 +41,13 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window), std::vector< std::shared_ptr > scrapers; scrapers.push_back(std::make_shared()); scrapers.push_back(std::make_shared()); - scraper_list->populate(scrapers, [&] (const std::shared_ptr& sc) { - return scraper_list->makeEntry(sc->getName(), sc, sc->getName() == Settings::getInstance()->getScraper()->getName()); - }); + + for(auto it = scrapers.begin(); it != scrapers.end(); it++) + scraper_list->add((*it)->getName(), *it, (*it)->getName() == Settings::getInstance()->getScraper()->getName()); + addSetting("Scraper:", scraper_list, [scraper_list] { - if(scraper_list->getSelected().size() > 0) - Settings::getInstance()->setScraper(scraper_list->getSelected()[0]->object); + Settings::getInstance()->setScraper(scraper_list->getSelected()); }); // scrape ratings