Redid message boxes.

This commit is contained in:
Aloshi 2014-03-15 12:18:50 -05:00
parent 45ffbf978c
commit 088b146fe9
13 changed files with 145 additions and 204 deletions

View file

@ -184,8 +184,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiFastSelect.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiFastSelect.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBoxOk.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBox.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBoxYesNo.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInputConfig.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInputConfig.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h
@ -264,8 +263,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiFastSelect.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiFastSelect.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBoxOk.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBoxYesNo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInputConfig.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInputConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp

View file

@ -88,7 +88,11 @@ void ComponentGrid::setEntry(const std::shared_ptr<GuiComponent>& comp, const Ei
addChild(comp.get()); addChild(comp.get());
if(!cursorValid() && canFocus) if(!cursorValid() && canFocus)
{
auto origCursor = mCursor;
mCursor = pos; mCursor = pos;
onCursorMoved(origCursor, mCursor);
}
updateCellComponent(mCells.back()); updateCellComponent(mCells.back());
updateSeparators(); updateSeparators();
@ -327,7 +331,8 @@ void ComponentGrid::onFocusGained()
bool ComponentGrid::cursorValid() bool ComponentGrid::cursorValid()
{ {
return getCellAt(mCursor) != NULL; GridEntry* e = getCellAt(mCursor);
return (e != NULL && e->canFocus);
} }
void ComponentGrid::update(int deltaTime) void ComponentGrid::update(int deltaTime)

View file

@ -61,16 +61,7 @@ void MenuComponent::updateGrid()
if(mButtons.size()) if(mButtons.size())
{ {
mButtonGrid = std::make_shared<ComponentGrid>(mWindow, Vector2i(mButtons.size(), 1)); mButtonGrid = makeButtonGrid(mWindow, mButtons);
float buttonGridWidth = 16.0f * mButtons.size(); // initialize to padding
for(int i = 0; i < (int)mButtons.size(); i++)
{
mButtonGrid->setEntry(mButtons.at(i), Vector2i(i, 0), true, false);
buttonGridWidth += mButtons.at(i)->getSize().x();
}
mButtonGrid->setSize(buttonGridWidth, mButtons.at(0)->getSize().y());
mGrid.setEntry(mButtonGrid, Vector2i(0, 2), true, false); mGrid.setEntry(mButtonGrid, Vector2i(0, 2), true, false);
}else{ }else{
@ -82,3 +73,23 @@ std::vector<HelpPrompt> MenuComponent::getHelpPrompts()
{ {
return mGrid.getHelpPrompts(); return mGrid.getHelpPrompts();
} }
std::shared_ptr<ComponentGrid> makeButtonGrid(Window* window, const std::vector< std::shared_ptr<ButtonComponent> >& buttons)
{
std::shared_ptr<ComponentGrid> buttonGrid = std::make_shared<ComponentGrid>(window, Vector2i(buttons.size(), 1));
float buttonGridWidth = 16.0f * buttons.size(); // initialize to padding
for(int i = 0; i < (int)buttons.size(); i++)
{
buttonGrid->setEntry(buttons.at(i), Vector2i(i, 0), true, false);
buttonGridWidth += buttons.at(i)->getSize().x();
}
for(unsigned int i = 0; i < buttons.size(); i++)
{
buttonGrid->setColWidthPerc(i, (buttons.at(i)->getSize().x() + 16) / buttonGridWidth);
}
buttonGrid->setSize(buttonGridWidth, buttons.at(0)->getSize().y());
return buttonGrid;
}

View file

@ -8,6 +8,8 @@
class ButtonComponent; class ButtonComponent;
std::shared_ptr<ComponentGrid> makeButtonGrid(Window* window, const std::vector< std::shared_ptr<ButtonComponent> >& buttons);
class MenuComponent : public GuiComponent class MenuComponent : public GuiComponent
{ {
public: public:

View file

@ -3,7 +3,7 @@
#include "../Sound.h" #include "../Sound.h"
#include "../Log.h" #include "../Log.h"
#include "../Settings.h" #include "../Settings.h"
#include "GuiMsgBoxYesNo.h" #include "GuiMsgBox.h"
#include "GuiSettings.h" #include "GuiSettings.h"
#include "GuiScraperStart.h" #include "GuiScraperStart.h"
@ -128,22 +128,22 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
ComponentListRow row; ComponentListRow row;
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBoxYesNo(window, "REALLY RESTART?", window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
[] { [] {
if(system("sudo shutdown -r now") != 0) if(system("sudo shutdown -r now") != 0)
LOG(LogWarning) << "Restart terminated with non-zero result!"; LOG(LogWarning) << "Restart terminated with non-zero result!";
})); }, "NO", nullptr));
}); });
row.addElement(std::make_shared<TextComponent>(window, "RESTART SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(window, "RESTART SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row); s->addRow(row);
row.elements.clear(); row.elements.clear();
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBoxYesNo(window, "REALLY SHUTDOWN?", window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES",
[] { [] {
if(system("sudo shutdown -h now") != 0) if(system("sudo shutdown -h now") != 0)
LOG(LogWarning) << "Shutdown terminated with non-zero result!"; LOG(LogWarning) << "Shutdown terminated with non-zero result!";
})); }, "NO", nullptr));
}); });
row.addElement(std::make_shared<TextComponent>(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row); s->addRow(row);
@ -152,12 +152,12 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
{ {
row.elements.clear(); row.elements.clear();
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBoxYesNo(window, "REALLY QUIT?", window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES",
[] { [] {
SDL_Event ev; SDL_Event ev;
ev.type = SDL_QUIT; ev.type = SDL_QUIT;
SDL_PushEvent(&ev); SDL_PushEvent(&ev);
})); }, "NO", nullptr));
}); });
row.addElement(std::make_shared<TextComponent>(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row); s->addRow(row);

View file

@ -4,7 +4,7 @@
#include "../components/AsyncReqComponent.h" #include "../components/AsyncReqComponent.h"
#include "../Settings.h" #include "../Settings.h"
#include "GuiGameScraper.h" #include "GuiGameScraper.h"
#include "GuiMsgBoxYesNo.h" #include "GuiMsgBox.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
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,
@ -35,7 +35,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
if(mDeleteFunc) if(mDeleteFunc)
{ {
auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; }; auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; };
auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui(new GuiMsgBoxYesNo(mWindow, "This will delete a file!\nAre you sure?", deleteFileAndSelf)); }; auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui(new GuiMsgBox(mWindow, "This will delete a file!\nAre you sure?", "YES", deleteFileAndSelf, "NO", nullptr)); };
mMenu.addButton("DELETE", "delete this game on disk", deleteBtnFunc); mMenu.addButton("DELETE", "delete this game on disk", deleteBtnFunc);
} }

69
src/guis/GuiMsgBox.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "GuiMsgBox.h"
#include "../Renderer.h"
#include "../components/TextComponent.h"
#include "../components/ButtonComponent.h"
#include "../components/MenuComponent.h" // for makeButtonGrid
#define BUTTON_VERT_PADDING 16.0f
GuiMsgBox::GuiMsgBox(Window* window, const std::string& text,
const std::string& name1, const std::function<void()>& func1,
const std::string& name2, const std::function<void()>& func2,
const std::string& name3, const std::function<void()>& func3) : GuiComponent(window),
mBackground(window, ":/frame.png"), mGrid(window, Eigen::Vector2i(1, 2))
{
float width = Renderer::getScreenWidth() * 0.6f; // max width
float minWidth = Renderer::getScreenWidth() * 0.3f; // minimum width
mMsg = std::make_shared<TextComponent>(mWindow, text, Font::get(FONT_SIZE_MEDIUM), 0x777777FF, true);
// create the buttons
mButtons.push_back(std::make_shared<ButtonComponent>(mWindow, name1, name1, std::bind(&GuiMsgBox::deleteMeAndCall, this, func1)));
if(!name2.empty())
mButtons.push_back(std::make_shared<ButtonComponent>(mWindow, name2, name3, std::bind(&GuiMsgBox::deleteMeAndCall, this, func2)));
if(!name3.empty())
mButtons.push_back(std::make_shared<ButtonComponent>(mWindow, name3, name3, std::bind(&GuiMsgBox::deleteMeAndCall, this, func3)));
// put the buttons into a ComponentGrid
mButtonGrid = makeButtonGrid(mWindow, mButtons);
mGrid.setEntry(mMsg, Eigen::Vector2i(0, 0), false, true);
mGrid.setEntry(mButtonGrid, Eigen::Vector2i(0, 1), true, false);
if(mMsg->getSize().x() > width)
{
mMsg->setSize(width, 0);
}else{
// mMsg is narrower than width
// are buttons?
if(mButtonGrid->getSize().x() < width)
{
width = std::max(mButtonGrid->getSize().x(), mMsg->getSize().x());
width = std::max(width, minWidth);
}
}
setSize(width, mMsg->getSize().y() + mButtonGrid->getSize().y() + BUTTON_VERT_PADDING);
// center for good measure
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2.0f, (Renderer::getScreenHeight() - mSize.y()) / 2.0f);
addChild(&mBackground);
addChild(&mGrid);
}
void GuiMsgBox::onSizeChanged()
{
mGrid.setSize(mSize);
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-16, -32));
mGrid.setRowHeightPerc(1, (mButtonGrid->getSize().y() + BUTTON_VERT_PADDING) / mSize.y());
}
void GuiMsgBox::deleteMeAndCall(const std::function<void()>& func)
{
if(func)
func();
delete this;
}

31
src/guis/GuiMsgBox.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include "../GuiComponent.h"
#include "../components/NinePatchComponent.h"
#include "../components/ComponentGrid.h"
class TextComponent;
class ButtonComponent;
class GuiMsgBox : public GuiComponent
{
public:
GuiMsgBox(Window* window, const std::string& text,
const std::string& name1 = "OK", const std::function<void()>& func1 = nullptr,
const std::string& name2 = "", const std::function<void()>& func2 = nullptr,
const std::string& name3 = "", const std::function<void()>& func3 = nullptr);
void onSizeChanged() override;
private:
void deleteMeAndCall(const std::function<void()>& func);
NinePatchComponent mBackground;
ComponentGrid mGrid;
std::shared_ptr<TextComponent> mMsg;
std::vector< std::shared_ptr<ButtonComponent> > mButtons;
std::shared_ptr<ComponentGrid> mButtonGrid;
};

View file

@ -1,50 +0,0 @@
#include "GuiMsgBoxOk.h"
#include "../Renderer.h"
#define MSG_WIDTH 0.8f
#define MSG_PADDING ((1 - MSG_WIDTH) / 2)
GuiMsgBoxOk::GuiMsgBoxOk(Window* window, const std::string& text, std::function<void()> callback) : GuiComponent(window),
mCallback(callback),
mBackground(window),
mText(window),
mOkText(window)
{
mText.setCentered(true);
mText.setColor(0x00BB00FF);
mText.setSize(Renderer::getScreenWidth() * MSG_WIDTH, 0);
mText.setText(text);
mOkText.setCentered(true);
mOkText.setColor(0x0044BBFF);
mOkText.setFont(Font::get(FONT_SIZE_SMALL));
mOkText.setSize(Renderer::getScreenWidth() * MSG_WIDTH, 0);
mOkText.setText("[A]");
mText.setPosition(Renderer::getScreenWidth() * MSG_PADDING, (Renderer::getScreenHeight() - mText.getSize().y() - mOkText.getSize().y()) / 2);
mOkText.setPosition(Renderer::getScreenWidth() * MSG_PADDING, mText.getPosition().y() + mText.getSize().y());
}
bool GuiMsgBoxOk::input(InputConfig* config, Input input)
{
if(input.value != 0 &&
(config->isMappedTo("a", input) || config->isMappedTo("b", input)))
{
if(mCallback)
mCallback();
delete this;
return true;
}
return false;
}
void GuiMsgBoxOk::render(const Eigen::Affine3f& parentTrans)
{
float height = mText.getSize().y() + mOkText.getSize().y();
Renderer::setMatrix(parentTrans);
Renderer::drawRect(0, (int)((Renderer::getScreenHeight() - height) / 2), Renderer::getScreenWidth(), (int)height, 0x111111FF);
mText.render(parentTrans);
mOkText.render(parentTrans);
}

View file

@ -1,25 +0,0 @@
#pragma once
#include "../GuiComponent.h"
#include "../components/TextComponent.h"
#include "../components/NinePatchComponent.h"
#include <functional>
//A simple popup message box with callbacks for when the user dismisses it.
//Make sure you remember to push it onto the window!
class GuiMsgBoxOk : public GuiComponent
{
public:
GuiMsgBoxOk(Window* window, const std::string& msg, std::function<void()> okCallback = nullptr);
bool input(InputConfig* config, Input input) override;
void render(const Eigen::Affine3f& parentTrans) override;
private:
std::function<void()> mCallback;
NinePatchComponent mBackground;
TextComponent mText;
TextComponent mOkText;
};

View file

@ -1,77 +0,0 @@
#include "GuiMsgBoxYesNo.h"
#include "../Renderer.h"
GuiMsgBoxYesNo::GuiMsgBoxYesNo(Window* window, const std::string& text, std::function<void()> yesCallback, std::function<void()> noCallback) : GuiComponent(window),
mYesCallback(yesCallback),
mNoCallback(noCallback),
mBackground(window),
mText(window),
mInputText(window)
{
const float paddingX = 32;
const float paddingY = 16;
const float maxWidth = Renderer::getScreenWidth() * 0.7f;
float width = mText.getFont()->sizeText(text).x() + paddingX;
if(width > maxWidth)
width = maxWidth;
mText.setCentered(true);
mText.setColor(0x777777FF);
mText.setPosition(paddingX / 2, paddingY / 2);
mText.setSize(width - paddingX, 0);
mText.setText(text);
mInputText.setCentered(true);
mInputText.setColor(0x0044BBFF);
mInputText.setFont(Font::get(FONT_SIZE_SMALL));
mInputText.setPosition(paddingX / 2, mText.getPosition().y() + mText.getSize().y());
mInputText.setSize(width - paddingX, 0);
mInputText.setText("[A - yes] [B - no]");
setSize(width, mInputText.getPosition().y() + mInputText.getSize().y() + paddingY/2);
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2);
mBackground.setImagePath(":/frame.png");
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-32, -32));
}
bool GuiMsgBoxYesNo::input(InputConfig* config, Input input)
{
if(input.value != 0)
{
if(config->isMappedTo("a", input))
{
if(mYesCallback)
mYesCallback();
delete this;
return true;
}else if(config->isMappedTo("b", input))
{
if(mNoCallback)
mNoCallback();
delete this;
return true;
}
}
return false;
}
void GuiMsgBoxYesNo::render(const Eigen::Affine3f& parentTrans)
{
Eigen::Affine3f trans = parentTrans * getTransform();
mBackground.render(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0, (int)(mText.getPosition().y() + mText.getSize().y()), (int)mSize.x(), 1, 0xC6C7C6FF);
mText.render(trans);
mInputText.render(trans);
renderChildren(trans);
}

View file

@ -1,25 +0,0 @@
#pragma once
#include "../GuiComponent.h"
#include "../components/TextComponent.h"
#include "../components/NinePatchComponent.h"
#include <functional>
//A simple "yes or no" popup box with callbacks for yes or no.
//Make sure you remember to push it onto the window!
class GuiMsgBoxYesNo : public GuiComponent
{
public:
GuiMsgBoxYesNo(Window* window, const std::string& msg, std::function<void()> yesCallback = nullptr, std::function<void()> noCallback = nullptr);
bool input(InputConfig* config, Input input) override;
void render(const Eigen::Affine3f& trans) override;
private:
std::function<void()> mYesCallback, mNoCallback;
NinePatchComponent mBackground;
TextComponent mText;
TextComponent mInputText;
};

View file

@ -1,6 +1,6 @@
#include "GuiScraperStart.h" #include "GuiScraperStart.h"
#include "GuiScraperLog.h" #include "GuiScraperLog.h"
#include "GuiMsgBoxYesNo.h" #include "GuiMsgBox.h"
#include "../components/TextComponent.h" #include "../components/TextComponent.h"
#include "../components/OptionListComponent.h" #include "../components/OptionListComponent.h"
@ -41,8 +41,10 @@ void GuiScraperStart::pressedStart()
{ {
if((*it)->getPlatformId() == PlatformIds::PLATFORM_UNKNOWN) if((*it)->getPlatformId() == PlatformIds::PLATFORM_UNKNOWN)
{ {
mWindow->pushGui(new GuiMsgBoxYesNo(mWindow, "Warning: some of your selected systems do not have a platform ID set. Results may be even more inaccurate than usual!\nContinue anyway?", mWindow->pushGui(new GuiMsgBox(mWindow,
std::bind(&GuiScraperStart::start, this))); "Warning: some of your selected systems do not have a platform ID set. Results may be even more inaccurate than usual!\nContinue anyway?",
"YES", std::bind(&GuiScraperStart::start, this),
"NO", nullptr));
return; return;
} }
} }