mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Added new text editing style to GuiMetaDataEd as per UI concepts.
This commit is contained in:
parent
ada4f83089
commit
91546ac2bc
|
@ -192,6 +192,7 @@ set(ES_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperStart.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperStart.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiTextEditPopup.h
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.h
|
||||||
|
@ -276,6 +277,7 @@ set(ES_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperStart.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperStart.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiTextEditPopup.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.cpp
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#include "components/TextEditComponent.h"
|
|
||||||
#include "components/RatingComponent.h"
|
|
||||||
#include "components/DateTimeComponent.h"
|
|
||||||
|
|
||||||
|
|
||||||
MetaDataDecl gameDecls[] = {
|
MetaDataDecl gameDecls[] = {
|
||||||
{"name", MD_STRING, "", false},
|
{"name", MD_STRING, "", false},
|
||||||
{"desc", MD_MULTILINE_STRING, "", false},
|
{"desc", MD_MULTILINE_STRING, "", false},
|
||||||
|
@ -133,37 +128,6 @@ boost::posix_time::ptime MetaDataList::getTime(const std::string& key) const
|
||||||
return string_to_ptime(get(key), "%Y%m%dT%H%M%S%F%q");
|
return string_to_ptime(get(key), "%Y%m%dT%H%M%S%F%q");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GuiComponent> MetaDataList::makeEditor(Window* window, MetaDataType as)
|
|
||||||
{
|
|
||||||
switch(as)
|
|
||||||
{
|
|
||||||
case MD_RATING:
|
|
||||||
{
|
|
||||||
return std::make_shared<RatingComponent>(window);
|
|
||||||
}
|
|
||||||
case MD_MULTILINE_STRING:
|
|
||||||
{
|
|
||||||
auto comp = std::make_shared<TextEditComponent>(window);
|
|
||||||
comp->setSize(comp->getSize().x(), comp->getSize().y() * 3);
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
case MD_DATE:
|
|
||||||
{
|
|
||||||
return std::make_shared<DateTimeComponent>(window);
|
|
||||||
}
|
|
||||||
case MD_TIME:
|
|
||||||
{
|
|
||||||
auto comp = std::make_shared<DateTimeComponent>(window);
|
|
||||||
comp->setDisplayMode(DateTimeComponent::DISP_RELATIVE_TO_NOW);
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return std::make_shared<TextEditComponent>(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//util function
|
//util function
|
||||||
boost::posix_time::ptime string_to_ptime(const std::string& str, const std::string& fmt)
|
boost::posix_time::ptime string_to_ptime(const std::string& str, const std::string& fmt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,8 +55,6 @@ public:
|
||||||
float getFloat(const std::string& key) const;
|
float getFloat(const std::string& key) const;
|
||||||
boost::posix_time::ptime getTime(const std::string& key) const;
|
boost::posix_time::ptime getTime(const std::string& key) const;
|
||||||
|
|
||||||
static std::shared_ptr<GuiComponent> makeEditor(Window* window, MetaDataType as);
|
|
||||||
|
|
||||||
inline MetaDataListType getType() const { return mType; }
|
inline MetaDataListType getType() const { return mType; }
|
||||||
inline const std::vector<MetaDataDecl>& getMDD() const { return getMDDByType(getType()); }
|
inline const std::vector<MetaDataDecl>& getMDD() const { return getMDDByType(getType()); }
|
||||||
|
|
||||||
|
@ -64,20 +62,3 @@ private:
|
||||||
MetaDataListType mType;
|
MetaDataListType mType;
|
||||||
std::map<std::string, std::string> mMap;
|
std::map<std::string, std::string> mMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//options for storing metadata...
|
|
||||||
//store internally everything as a string - this is all going to be read to/from XML anyway, after all
|
|
||||||
// - problem: this does not play nice with lists of values
|
|
||||||
//store using individual get/set functions ala Settings - this is a fair amount of work but the most explicit and type-safe, for better or worse
|
|
||||||
|
|
||||||
//let's think about some of the special types we would like to support...
|
|
||||||
//image paths, sound paths, ratings, play counts
|
|
||||||
//these get represented behind-the-scenes as strings, floats, and integers, and are eventually saved as strings
|
|
||||||
//the only specialty is how they're edited and viewed, really
|
|
||||||
|
|
||||||
//so we need...
|
|
||||||
//to be able to iterate through the available metadata
|
|
||||||
//create components designed to either DISPLAY or EDIT a given piece of metadata
|
|
||||||
//save and load metadata
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include "../Log.h"
|
#include "../Log.h"
|
||||||
#include "../Util.h"
|
#include "../Util.h"
|
||||||
|
|
||||||
DateTimeComponent::DateTimeComponent(Window* window) : GuiComponent(window),
|
DateTimeComponent::DateTimeComponent(Window* window, DisplayMode dispMode) : GuiComponent(window),
|
||||||
mEditing(false), mEditIndex(0), mDisplayMode(DISP_DATE), mRelativeUpdateAccumulator(0),
|
mEditing(false), mEditIndex(0), mDisplayMode(dispMode), mRelativeUpdateAccumulator(0),
|
||||||
mColor(0x000000FF)
|
mColor(0x000000FF)
|
||||||
{
|
{
|
||||||
mSize << 64, (float)getFont()->getHeight();
|
mSize << 64, (float)getFont()->getHeight();
|
||||||
|
|
|
@ -8,8 +8,14 @@
|
||||||
class DateTimeComponent : public GuiComponent
|
class DateTimeComponent : public GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Display mode will initialize to DISP_DATE.
|
enum DisplayMode
|
||||||
DateTimeComponent(Window* window);
|
{
|
||||||
|
DISP_DATE,
|
||||||
|
DISP_DATE_TIME,
|
||||||
|
DISP_RELATIVE_TO_NOW
|
||||||
|
};
|
||||||
|
|
||||||
|
DateTimeComponent(Window* window, DisplayMode dispMode = DISP_DATE);
|
||||||
|
|
||||||
void setValue(const std::string& val) override;
|
void setValue(const std::string& val) override;
|
||||||
std::string getValue() const override;
|
std::string getValue() const override;
|
||||||
|
@ -18,13 +24,6 @@ public:
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
void render(const Eigen::Affine3f& parentTrans) override;
|
void render(const Eigen::Affine3f& parentTrans) override;
|
||||||
|
|
||||||
enum DisplayMode
|
|
||||||
{
|
|
||||||
DISP_DATE,
|
|
||||||
DISP_DATE_TIME,
|
|
||||||
DISP_RELATIVE_TO_NOW
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set how the point in time will be displayed:
|
// Set how the point in time will be displayed:
|
||||||
// * DISP_DATE - only display the date.
|
// * DISP_DATE - only display the date.
|
||||||
// * DISP_DATE_TIME - display both the date and the time on that date.
|
// * DISP_DATE_TIME - display both the date and the time on that date.
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
std::string getValue() const override;
|
std::string getValue() const override;
|
||||||
|
|
||||||
inline bool isEditing() const { return mEditing; };
|
inline bool isEditing() const { return mEditing; };
|
||||||
|
inline const std::shared_ptr<Font>& getFont() const { return mFont; }
|
||||||
|
|
||||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
#include "GuiMsgBox.h"
|
#include "GuiMsgBox.h"
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include "../components/TextEditComponent.h"
|
||||||
|
#include "../components/DateTimeComponent.h"
|
||||||
|
#include "../components/RatingComponent.h"
|
||||||
|
#include "GuiTextEditPopup.h"
|
||||||
|
|
||||||
GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector<MetaDataDecl>& mdd, ScraperSearchParams scraperParams,
|
GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector<MetaDataDecl>& mdd, ScraperSearchParams scraperParams,
|
||||||
const std::string& header, std::function<void()> saveCallback, std::function<void()> deleteFunc) : GuiComponent(window),
|
const std::string& header, std::function<void()> saveCallback, std::function<void()> deleteFunc) : GuiComponent(window),
|
||||||
mScraperParams(scraperParams),
|
mScraperParams(scraperParams),
|
||||||
|
@ -22,10 +27,61 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
|
||||||
// populate list
|
// populate list
|
||||||
for(auto iter = mdd.begin(); iter != mdd.end(); iter++)
|
for(auto iter = mdd.begin(); iter != mdd.end(); iter++)
|
||||||
{
|
{
|
||||||
auto ed = MetaDataList::makeEditor(mWindow, iter->type);
|
std::shared_ptr<GuiComponent> ed;
|
||||||
|
|
||||||
|
// create ed and add it (and any related components) to mMenu
|
||||||
|
// ed's value will be set below
|
||||||
|
switch(iter->type)
|
||||||
|
{
|
||||||
|
case MD_RATING:
|
||||||
|
{
|
||||||
|
ed = std::make_shared<RatingComponent>(window);
|
||||||
|
mMenu.addWithLabel(iter->key, ed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MD_DATE:
|
||||||
|
{
|
||||||
|
ed = std::make_shared<DateTimeComponent>(window);
|
||||||
|
mMenu.addWithLabel(iter->key, ed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MD_TIME:
|
||||||
|
{
|
||||||
|
ed = std::make_shared<DateTimeComponent>(window, DateTimeComponent::DISP_RELATIVE_TO_NOW);
|
||||||
|
mMenu.addWithLabel(iter->key, ed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MD_MULTILINE_STRING:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// MD_STRING
|
||||||
|
ComponentListRow row;
|
||||||
|
auto lbl = std::make_shared<TextComponent>(mWindow, iter->key, Font::get(FONT_SIZE_SMALL), 0x777777FF);
|
||||||
|
row.addElement(lbl, true); // label
|
||||||
|
|
||||||
|
ed = std::make_shared<TextComponent>(window, "", Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT), 0x777777FF);
|
||||||
|
row.addElement(ed, true);
|
||||||
|
|
||||||
|
auto bracket = std::make_shared<ImageComponent>(mWindow);
|
||||||
|
bracket->setImage(":/sq_bracket.png");
|
||||||
|
bracket->setResize(Eigen::Vector2f(0, lbl->getSize().y() * 0.8f));
|
||||||
|
row.addElement(bracket, false);
|
||||||
|
|
||||||
|
bool multiLine = iter->type == MD_MULTILINE_STRING;
|
||||||
|
const std::string& title = iter->key;
|
||||||
|
auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; // ok callback (apply new value to ed)
|
||||||
|
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
||||||
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, title, ed->getValue(), updateVal, multiLine));
|
||||||
|
});
|
||||||
|
|
||||||
|
mMenu.addRow(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ed);
|
||||||
ed->setValue(mMetaData->get(iter->key));
|
ed->setValue(mMetaData->get(iter->key));
|
||||||
mEditors.push_back(ed);
|
mEditors.push_back(ed);
|
||||||
mMenu.addWithLabel(iter->key, ed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add buttons
|
//add buttons
|
||||||
|
|
59
src/guis/GuiTextEditPopup.cpp
Normal file
59
src/guis/GuiTextEditPopup.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "GuiTextEditPopup.h"
|
||||||
|
#include "../components/MenuComponent.h"
|
||||||
|
|
||||||
|
using namespace Eigen;
|
||||||
|
|
||||||
|
GuiTextEditPopup::GuiTextEditPopup(Window* window, const std::string& title, const std::string& initValue,
|
||||||
|
const std::function<void(const std::string&)>& okCallback, bool multiLine, const char* acceptBtnText)
|
||||||
|
: GuiComponent(window), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 3)), mMultiLine(multiLine)
|
||||||
|
{
|
||||||
|
addChild(&mBackground);
|
||||||
|
addChild(&mGrid);
|
||||||
|
|
||||||
|
mTitle = std::make_shared<TextComponent>(mWindow, strToUpper(title), Font::get(FONT_SIZE_MEDIUM), 0x777777FF, true);
|
||||||
|
|
||||||
|
mText = std::make_shared<TextEditComponent>(mWindow);
|
||||||
|
mText->setValue(initValue);
|
||||||
|
|
||||||
|
std::vector< std::shared_ptr<ButtonComponent> > buttons;
|
||||||
|
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, acceptBtnText, acceptBtnText, [this, okCallback] { okCallback(mText->getValue()); delete this; }));
|
||||||
|
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "CANCEL", "discard changes", [this] { delete this; }));
|
||||||
|
|
||||||
|
mButtonGrid = makeButtonGrid(mWindow, buttons);
|
||||||
|
|
||||||
|
mGrid.setEntry(mTitle, Vector2i(0, 0), false, true);
|
||||||
|
mGrid.setEntry(mText, Vector2i(0, 1), true, true);
|
||||||
|
mGrid.setEntry(mButtonGrid, Vector2i(0, 2), true, false);
|
||||||
|
|
||||||
|
float textHeight = mText->getFont()->getHeight();
|
||||||
|
if(multiLine)
|
||||||
|
textHeight *= 3;
|
||||||
|
|
||||||
|
setSize(Renderer::getScreenWidth() * 0.5f, mTitle->getFont()->getHeight() + textHeight + mButtonGrid->getSize().y());
|
||||||
|
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiTextEditPopup::onSizeChanged()
|
||||||
|
{
|
||||||
|
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-32, -32));
|
||||||
|
|
||||||
|
// update grid
|
||||||
|
mGrid.setRowHeightPerc(0, mTitle->getFont()->getHeight() / mSize.y());
|
||||||
|
mGrid.setRowHeightPerc(2, mButtonGrid->getSize().y() / mSize.y());
|
||||||
|
mGrid.setSize(mSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTextEditPopup::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
|
if(GuiComponent::input(config, input))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// pressing back when not text editing closes us
|
||||||
|
if(config->isMappedTo("b", input) && input.value)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
27
src/guis/GuiTextEditPopup.h
Normal file
27
src/guis/GuiTextEditPopup.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include "../GuiComponent.h"
|
||||||
|
|
||||||
|
#include "../components/NinePatchComponent.h"
|
||||||
|
#include "../components/ButtonComponent.h"
|
||||||
|
#include "../components/ComponentGrid.h"
|
||||||
|
#include "../components/TextEditComponent.h"
|
||||||
|
#include "../components/TextComponent.h"
|
||||||
|
|
||||||
|
class GuiTextEditPopup : public GuiComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiTextEditPopup(Window* window, const std::string& title, const std::string& initValue,
|
||||||
|
const std::function<void(const std::string&)>& okCallback, bool multiLine, const char* acceptBtnText = "OK");
|
||||||
|
|
||||||
|
bool input(InputConfig* config, Input input);
|
||||||
|
void onSizeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NinePatchComponent mBackground;
|
||||||
|
ComponentGrid mGrid;
|
||||||
|
|
||||||
|
std::shared_ptr<TextComponent> mTitle;
|
||||||
|
std::shared_ptr<TextEditComponent> mText;
|
||||||
|
std::shared_ptr<ComponentGrid> mButtonGrid;
|
||||||
|
|
||||||
|
bool mMultiLine;
|
||||||
|
};
|
Loading…
Reference in a new issue