mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-28 17:15:38 +00:00
First implementation of the new ComponentList stuff.
This commit is contained in:
parent
139fc720ac
commit
c525d994d3
|
@ -162,6 +162,7 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AsyncReqComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ButtonComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentGrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentList.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/IList.h
|
||||
|
@ -244,6 +245,7 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AsyncReqComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ButtonComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentGrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentList.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp
|
||||
|
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 17 KiB |
|
@ -37,7 +37,7 @@ namespace Renderer
|
|||
void setMatrix(float* mat);
|
||||
void setMatrix(const Eigen::Affine3f& transform);
|
||||
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color);
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color, GLenum blend_sfactor = GL_SRC_ALPHA, GLenum blend_dfactor = GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color)
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color, GLenum blend_sfactor, GLenum blend_dfactor)
|
||||
{
|
||||
#ifdef USE_OPENGL_ES
|
||||
GLshort points[12];
|
||||
|
@ -90,7 +90,7 @@ namespace Renderer {
|
|||
buildGLColorArray(colors, color, 6);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc(blend_sfactor, blend_dfactor);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
|
|
164
src/components/ComponentList.cpp
Normal file
164
src/components/ComponentList.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include "ComponentList.h"
|
||||
|
||||
#define TOTAL_HORIZONTAL_PADDING_PX 12
|
||||
|
||||
ComponentList::ComponentList(Window* window) : IList<ComponentListRow, void*>(window, LIST_SCROLL_STYLE_SLOW, LIST_NEVER_LOOP)
|
||||
{
|
||||
mSelectorBarOffset = 0;
|
||||
}
|
||||
|
||||
void ComponentList::addRow(const ComponentListRow& row)
|
||||
{
|
||||
IList<ComponentListRow, void*>::Entry e;
|
||||
e.name = "";
|
||||
e.object = NULL;
|
||||
e.data = row;
|
||||
|
||||
this->add(e);
|
||||
|
||||
for(auto it = mEntries.back().data.elements.begin(); it != mEntries.back().data.elements.end(); it++)
|
||||
addChild(it->component.get());
|
||||
|
||||
updateElementSize(mEntries.back().data);
|
||||
updateElementPosition(mEntries.back().data);
|
||||
}
|
||||
|
||||
void ComponentList::onSizeChanged()
|
||||
{
|
||||
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||
{
|
||||
updateElementSize(it->data);
|
||||
updateElementPosition(it->data);
|
||||
}
|
||||
}
|
||||
|
||||
bool ComponentList::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(size() == 0)
|
||||
return false;
|
||||
|
||||
// give it to the current row's input handler
|
||||
if(mEntries.at(mCursor).data.input_handler && mEntries.at(mCursor).data.input_handler(config, input))
|
||||
return true;
|
||||
|
||||
// input handler didn't consume the input - try to scroll
|
||||
if(config->isMappedTo("up", input))
|
||||
{
|
||||
return listInput(input.value != 0 ? -1 : 0);
|
||||
}else if(config->isMappedTo("down", input))
|
||||
{
|
||||
return listInput(input.value != 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComponentList::update(int deltaTime)
|
||||
{
|
||||
listUpdate(deltaTime);
|
||||
}
|
||||
|
||||
void ComponentList::onCursorChanged(const CursorState& state)
|
||||
{
|
||||
// update the selector bar position
|
||||
// in the future this might be animated
|
||||
mSelectorBarOffset = 0;
|
||||
for(int i = 0; i < mCursor; i++)
|
||||
{
|
||||
mSelectorBarOffset += getRowHeight(mEntries.at(i).data);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentList::render(const Eigen::Affine3f& parentTrans)
|
||||
{
|
||||
Eigen::Affine3f trans = parentTrans * getTransform();
|
||||
|
||||
// clip our entries inside our bounds
|
||||
Eigen::Vector3f dim(mSize.x(), mSize.y(), 0);
|
||||
dim = trans * dim - trans.translation();
|
||||
Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(),
|
||||
(int)trans.translation().y()), Eigen::Vector2i((int)dim.x(), (int)dim.y()));
|
||||
|
||||
// draw our entries
|
||||
renderChildren(trans);
|
||||
|
||||
Renderer::popClipRect();
|
||||
|
||||
// draw selector bar
|
||||
Renderer::setMatrix(trans);
|
||||
|
||||
// inversion: src * (1 - dst) + dst * 0 = where src = 1
|
||||
// need a function that goes roughly 0x777777 -> 0xFFFFFF
|
||||
// and 0xFFFFFF -> 0x777777
|
||||
// (1 - dst) + 0x77
|
||||
|
||||
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)getRowHeight(mEntries.at(mCursor).data), 0xFFFFFFFF,
|
||||
GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
||||
Renderer::drawRect(0, (int)mSelectorBarOffset, (int)mSize.x(), (int)getRowHeight(mEntries.at(mCursor).data), 0x777777FF,
|
||||
GL_ONE, GL_ONE);
|
||||
|
||||
// draw separators
|
||||
float y = 0;
|
||||
for(unsigned int i = 0; i < mEntries.size(); i++)
|
||||
{
|
||||
Renderer::drawRect(0, (int)y, (int)mSize.x(), 1, 0xC6C7C688);
|
||||
y += getRowHeight(mEntries.at(i).data);
|
||||
}
|
||||
Renderer::drawRect(0, (int)y, (int)mSize.x(), 1, 0xC6C7C688);
|
||||
}
|
||||
|
||||
float ComponentList::getRowHeight(const ComponentListRow& row)
|
||||
{
|
||||
// returns the highest component height found in the row
|
||||
float height = 0;
|
||||
for(unsigned int i = 0; i < row.elements.size(); i++)
|
||||
{
|
||||
if(row.elements.at(i).component->getSize().y() > height)
|
||||
height = row.elements.at(i).component->getSize().y();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void ComponentList::updateElementPosition(const ComponentListRow& row)
|
||||
{
|
||||
float yOffset = 0;
|
||||
for(auto it = mEntries.begin(); it != mEntries.end() && &it->data != &row; it++)
|
||||
{
|
||||
yOffset += getRowHeight(it->data);
|
||||
}
|
||||
|
||||
// assumes updateElementSize has already been called
|
||||
float rowHeight = getRowHeight(row);
|
||||
|
||||
float x = TOTAL_HORIZONTAL_PADDING_PX / 2;
|
||||
for(unsigned int i = 0; i < row.elements.size(); i++)
|
||||
{
|
||||
const auto comp = row.elements.at(i).component;
|
||||
|
||||
// center vertically
|
||||
comp->setPosition(x, (rowHeight - comp->getSize().y()) / 2 + yOffset);
|
||||
x += comp->getSize().x();
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentList::updateElementSize(const ComponentListRow& row)
|
||||
{
|
||||
float width = mSize.x() - TOTAL_HORIZONTAL_PADDING_PX;
|
||||
std::vector< std::shared_ptr<GuiComponent> > resizeVec;
|
||||
|
||||
for(auto it = row.elements.begin(); it != row.elements.end(); it++)
|
||||
{
|
||||
if(it->resize_width)
|
||||
resizeVec.push_back(it->component);
|
||||
else
|
||||
width -= it->component->getSize().x();
|
||||
}
|
||||
|
||||
// redistribute the "unused" width equally among the components with resize_width set to true
|
||||
width = width / resizeVec.size();
|
||||
for(auto it = resizeVec.begin(); it != resizeVec.end(); it++)
|
||||
{
|
||||
(*it)->setSize(width, (*it)->getSize().y());
|
||||
}
|
||||
}
|
48
src/components/ComponentList.h
Normal file
48
src/components/ComponentList.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include "IList.h"
|
||||
#include <functional>
|
||||
|
||||
struct ComponentListElement
|
||||
{
|
||||
ComponentListElement(const std::shared_ptr<GuiComponent>& cmp = nullptr, bool resize_w = true) : component(cmp), resize_width(resize_w) { };
|
||||
|
||||
std::shared_ptr<GuiComponent> component;
|
||||
bool resize_width;
|
||||
};
|
||||
|
||||
struct ComponentListRow
|
||||
{
|
||||
std::vector<ComponentListElement> elements;
|
||||
std::function<bool(InputConfig*, Input)> input_handler;
|
||||
|
||||
inline void addElement(const std::shared_ptr<GuiComponent>& component, bool resize_width)
|
||||
{
|
||||
elements.push_back(ComponentListElement(component, resize_width));
|
||||
}
|
||||
};
|
||||
|
||||
class ComponentList : public IList<ComponentListRow, void*>
|
||||
{
|
||||
public:
|
||||
ComponentList(Window* window);
|
||||
|
||||
void addRow(const ComponentListRow& row);
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
void update(int deltaTime) override;
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
||||
void onSizeChanged() override;
|
||||
|
||||
protected:
|
||||
void onCursorChanged(const CursorState& state) override;
|
||||
|
||||
private:
|
||||
void updateElementPosition(const ComponentListRow& row);
|
||||
void updateElementSize(const ComponentListRow& row);
|
||||
|
||||
float getRowHeight(const ComponentListRow& row);
|
||||
|
||||
float mSelectorBarOffset;
|
||||
};
|
|
@ -14,18 +14,38 @@ enum CursorState
|
|||
CURSOR_SCROLLING
|
||||
};
|
||||
|
||||
enum ListLoopType
|
||||
{
|
||||
LIST_ALWAYS_LOOP,
|
||||
LIST_PAUSE_AT_END,
|
||||
LIST_NEVER_LOOP
|
||||
};
|
||||
|
||||
struct ScrollTier
|
||||
{
|
||||
int length; // how long we stay on this level before going to the next
|
||||
int scrollDelay; // how long between scrolls
|
||||
};
|
||||
|
||||
const int SCROLL_SPEED_COUNT = 3;
|
||||
const ScrollTier SCROLL_SPEED[SCROLL_SPEED_COUNT] = {
|
||||
struct ScrollTierList
|
||||
{
|
||||
const int count;
|
||||
const ScrollTier* tiers;
|
||||
};
|
||||
|
||||
// default scroll tiers
|
||||
const ScrollTier QUICK_SCROLL_TIERS[] = {
|
||||
{500, 500},
|
||||
{5000, 114},
|
||||
{0, 8}
|
||||
};
|
||||
const ScrollTierList LIST_SCROLL_STYLE_QUICK = { 3, QUICK_SCROLL_TIERS };
|
||||
|
||||
const ScrollTier SLOW_SCROLL_TIERS[] = {
|
||||
{500, 500},
|
||||
{0, 150}
|
||||
};
|
||||
const ScrollTierList LIST_SCROLL_STYLE_SLOW = { 2, SLOW_SCROLL_TIERS };
|
||||
|
||||
template <typename EntryData, typename UserData>
|
||||
class IList : public GuiComponent
|
||||
|
@ -52,10 +72,14 @@ protected:
|
|||
ImageComponent mGradient;
|
||||
std::shared_ptr<Font> mTitleOverlayFont;
|
||||
|
||||
const ScrollTierList& mTierList;
|
||||
const ListLoopType mLoopType;
|
||||
|
||||
std::vector<Entry> mEntries;
|
||||
|
||||
public:
|
||||
IList(Window* window) : GuiComponent(window), mGradient(window)
|
||||
IList(Window* window, const ScrollTierList& tierList = LIST_SCROLL_STYLE_QUICK, const ListLoopType& loopType = LIST_PAUSE_AT_END) : GuiComponent(window),
|
||||
mGradient(window), mTierList(tierList), mLoopType(loopType)
|
||||
{
|
||||
mCursor = 0;
|
||||
mScrollTier = 0;
|
||||
|
@ -125,7 +149,7 @@ public:
|
|||
}
|
||||
|
||||
// entry management
|
||||
void add(Entry e)
|
||||
void add(const Entry& e)
|
||||
{
|
||||
mEntries.push_back(e);
|
||||
}
|
||||
|
@ -159,19 +183,22 @@ protected:
|
|||
}
|
||||
|
||||
|
||||
void listInput(int velocity) // a velocity of 0 = stop scrolling
|
||||
bool listInput(int velocity) // a velocity of 0 = stop scrolling
|
||||
{
|
||||
mScrollVelocity = velocity;
|
||||
mScrollTier = 0;
|
||||
mScrollTierAccumulator = 0;
|
||||
mScrollCursorAccumulator = 0;
|
||||
|
||||
int prevCursor = mCursor;
|
||||
scroll(mScrollVelocity);
|
||||
return (prevCursor != mCursor);
|
||||
}
|
||||
|
||||
void listUpdate(int deltaTime)
|
||||
{
|
||||
// update the title overlay opacity
|
||||
const int dir = (mScrollTier >= SCROLL_SPEED_COUNT - 1) ? 1 : -1; // fade in if scroll tier is >= 1, otherwise fade out
|
||||
const int dir = (mScrollTier >= mTierList.count - 1) ? 1 : -1; // fade in if scroll tier is >= 1, otherwise fade out
|
||||
int op = mTitleOverlayOpacity + deltaTime*dir; // we just do a 1-to-1 time -> opacity, no scaling
|
||||
if(op >= 255)
|
||||
mTitleOverlayOpacity = 255;
|
||||
|
@ -189,16 +216,16 @@ protected:
|
|||
// we delay scrolling until after scroll tier has updated so isScrolling() returns accurately during onCursorChanged callbacks
|
||||
// we don't just do scroll tier first because it would not catch the scrollDelay == tier length case
|
||||
int scrollCount = 0;
|
||||
while(mScrollCursorAccumulator >= SCROLL_SPEED[mScrollTier].scrollDelay)
|
||||
while(mScrollCursorAccumulator >= mTierList.tiers[mScrollTier].scrollDelay)
|
||||
{
|
||||
mScrollCursorAccumulator -= SCROLL_SPEED[mScrollTier].scrollDelay;
|
||||
mScrollCursorAccumulator -= mTierList.tiers[mScrollTier].scrollDelay;
|
||||
scrollCount++;
|
||||
}
|
||||
|
||||
// are we ready to go even FASTER?
|
||||
while(mScrollTier < SCROLL_SPEED_COUNT - 1 && mScrollTierAccumulator >= SCROLL_SPEED[mScrollTier].length)
|
||||
while(mScrollTier < mTierList.count - 1 && mScrollTierAccumulator >= mTierList.tiers[mScrollTier].length)
|
||||
{
|
||||
mScrollTierAccumulator -= SCROLL_SPEED[mScrollTier].length;
|
||||
mScrollTierAccumulator -= mTierList.tiers[mScrollTier].length;
|
||||
mScrollTier++;
|
||||
}
|
||||
|
||||
|
@ -237,16 +264,17 @@ protected:
|
|||
// stop at the end if we've been holding down the button for a long time or
|
||||
// we're scrolling faster than one item at a time (e.g. page up/down)
|
||||
// otherwise, loop around
|
||||
if(mScrollTier > 0 || absAmt > 1)
|
||||
if((mLoopType == LIST_PAUSE_AT_END && (mScrollTier > 0 || absAmt > 1)) ||
|
||||
mLoopType == LIST_NEVER_LOOP)
|
||||
{
|
||||
if(cursor < 0)
|
||||
cursor = 0;
|
||||
else if(cursor >= size())
|
||||
cursor = size() - 1;
|
||||
}else{
|
||||
if(cursor < 0)
|
||||
while(cursor < 0)
|
||||
cursor += size();
|
||||
else if(cursor >= size())
|
||||
while(cursor >= size())
|
||||
cursor -= size();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include "MenuComponent.h"
|
||||
|
||||
MenuComponent::MenuComponent(Window* window, const char* title) : GuiComponent(window),
|
||||
mBackground(window), mTitle(window), mList(window)
|
||||
{
|
||||
mBackground.setImagePath(":/frame.png");
|
||||
|
||||
mTitle.setText(title);
|
||||
mTitle.setCentered(true);
|
||||
|
||||
addChild(&mBackground);
|
||||
addChild(&mTitle);
|
||||
addChild(&mList);
|
||||
|
||||
setSize(Renderer::getScreenWidth() * 0.6f, Renderer::getScreenHeight() * 0.8f);
|
||||
}
|
||||
|
||||
void MenuComponent::onSizeChanged()
|
||||
{
|
||||
mBackground.fitTo(mSize, Eigen::Vector3f::Zero(), Eigen::Vector2f(-2, -2));
|
||||
|
||||
mTitle.setSize(mSize.x(), (float)mTitle.getFont()->getHeight());
|
||||
|
||||
mList.setPosition(0, mTitle.getSize().y());
|
||||
mList.setSize(mSize.x(), mSize.y() - mTitle.getSize().y());
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "NinePatchComponent.h"
|
||||
#include "ComponentList.h"
|
||||
#include "TextComponent.h"
|
||||
|
||||
class MenuComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
MenuComponent(Window* window, const char* title);
|
||||
|
||||
void onSizeChanged() override;
|
||||
|
||||
inline void addRow(const ComponentListRow& row) { mList.addRow(row); }
|
||||
|
||||
private:
|
||||
NinePatchComponent mBackground;
|
||||
TextComponent mTitle;
|
||||
ComponentList mList;
|
||||
};
|
|
@ -9,9 +9,10 @@ TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
|||
{
|
||||
}
|
||||
|
||||
TextComponent::TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window),
|
||||
TextComponent::TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, unsigned int color, Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window),
|
||||
mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true, true), mCentered(false)
|
||||
{
|
||||
setColor(color);
|
||||
setText(text);
|
||||
setFont(font);
|
||||
setPosition(pos);
|
||||
|
|
|
@ -15,7 +15,7 @@ class TextComponent : public GuiComponent
|
|||
{
|
||||
public:
|
||||
TextComponent(Window* window);
|
||||
TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero());
|
||||
TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, unsigned int color = 0x000000FF, Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero());
|
||||
|
||||
void setFont(std::shared_ptr<Font> font);
|
||||
void onSizeChanged() override;
|
||||
|
|
|
@ -2,72 +2,93 @@
|
|||
#include "GuiSettingsMenu.h"
|
||||
#include "GuiScraperStart.h"
|
||||
#include "../Window.h"
|
||||
#include "../Sound.h"
|
||||
#include "../Log.h"
|
||||
#include "GuiMsgBoxYesNo.h"
|
||||
|
||||
GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mBackground(window, ":/button.png"), mList(window)
|
||||
GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "Main Menu")
|
||||
{
|
||||
mList.add("Settings", [&] {
|
||||
mWindow->pushGui(new GuiSettingsMenu(mWindow));
|
||||
}, 0);
|
||||
|
||||
mList.add("Scrape Systems", [&] {
|
||||
mWindow->pushGui(new GuiScraperStart(mWindow));
|
||||
}, 0);
|
||||
|
||||
mList.add("Restart", [] {
|
||||
if(system("sudo shutdown -r now") != 0)
|
||||
LOG(LogWarning) << "Restart terminated with non-zero result!";
|
||||
}, 0);
|
||||
|
||||
mList.add("Shutdown", [] {
|
||||
if(system("sudo shutdown -h now") != 0)
|
||||
LOG(LogWarning) << "Shutdown terminated with non-zero result!";
|
||||
}, 1);
|
||||
|
||||
mList.add("Exit", [] {
|
||||
SDL_Event* ev = new SDL_Event();
|
||||
ev->type = SDL_QUIT;
|
||||
SDL_PushEvent(ev);
|
||||
}, 0);
|
||||
struct MenuEntry
|
||||
{
|
||||
const char* name;
|
||||
unsigned int color;
|
||||
bool add_arrow;
|
||||
std::function<void()> func;
|
||||
};
|
||||
|
||||
MenuEntry entries[] = {
|
||||
{ "GENERAL SETTINGS", 0x777777FF, true,
|
||||
[this] { mWindow->pushGui(new GuiSettingsMenu(mWindow)); }
|
||||
},
|
||||
{ "SCRAPE NOW", 0x777777FF, true,
|
||||
[this] { mWindow->pushGui(new GuiScraperStart(mWindow)); }
|
||||
},
|
||||
{ "RESTART SYSTEM", 0x990000FF, false,
|
||||
[this] {
|
||||
mWindow->pushGui(new GuiMsgBoxYesNo(mWindow, "Do you really want to restart the system?",
|
||||
[] {
|
||||
if(system("sudo shutdown -r now") != 0)
|
||||
LOG(LogWarning) << "Restart terminated with non-zero result!";
|
||||
}));
|
||||
}
|
||||
},
|
||||
{ "SHUTDOWN SYSTEM", 0x990000FF, false,
|
||||
[this] {
|
||||
mWindow->pushGui(new GuiMsgBoxYesNo(mWindow, "Do you really want to shutdown the system?",
|
||||
[] {
|
||||
if(system("sudo shutdown -h now") != 0)
|
||||
LOG(LogWarning) << "Shutdown terminated with non-zero result!";
|
||||
}));
|
||||
}
|
||||
},
|
||||
{ "EXIT EMULATIONSTATION", 0x990000FF, false,
|
||||
[] {
|
||||
SDL_Event ev;
|
||||
ev.type = SDL_QUIT;
|
||||
SDL_PushEvent(&ev);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
mMenu.setPosition((mSize.x() - mMenu.getSize().x()) / 2, (mSize.y() - mMenu.getSize().y()) / 2);
|
||||
|
||||
mList.setPosition(mSize.x() * 0.175f, mSize.y() * 0.05f);
|
||||
mList.setSize(mSize.x() * 0.65f, mSize.y() * 0.9f);
|
||||
std::shared_ptr<Font> font = Font::get(FONT_SIZE_LARGE);
|
||||
|
||||
mTheme = ThemeData::getDefault();
|
||||
// populate the list
|
||||
ComponentListRow row;
|
||||
|
||||
using namespace ThemeFlags;
|
||||
mBackground.applyTheme(mTheme, "menu", "windowBackground", PATH);
|
||||
mBackground.fitTo(Eigen::Vector2f(mList.getSize().x(), mSize.y()), Eigen::Vector3f(mList.getPosition().x(), 0, 0));
|
||||
addChild(&mBackground);
|
||||
for(int i = 0; i < (sizeof(entries) / sizeof(entries[0])); i++)
|
||||
{
|
||||
row.elements.clear();
|
||||
row.addElement(std::make_shared<TextComponent>(mWindow, entries[i].name, font, entries[i].color), true);
|
||||
|
||||
mList.setFont(Font::get((int)(0.09f * Renderer::getScreenHeight())));
|
||||
mList.setSelectorColor(0xBBBBBBFF);
|
||||
mList.setColor(0, 0x0000FFFF);
|
||||
mList.setColor(1, 0xFF0000FF);
|
||||
mList.applyTheme(mTheme, "menu", "menulist", FONT_PATH | COLOR | SOUND);
|
||||
if(entries[i].add_arrow)
|
||||
row.addElement(std::make_shared<TextComponent>(mWindow, ">", font, entries[i].color), false);
|
||||
|
||||
Sound::getFromTheme(mTheme, "menu", "menuOpen")->play();
|
||||
std::function<void()>& execFunc = entries[i].func;
|
||||
row.input_handler = [execFunc](InputConfig* config, Input input) -> bool
|
||||
{
|
||||
if(config->isMappedTo("a", input) && input.value != 0)
|
||||
{
|
||||
execFunc();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
addChild(&mList);
|
||||
mMenu.addRow(row);
|
||||
}
|
||||
|
||||
addChild(&mMenu);
|
||||
}
|
||||
|
||||
bool GuiMenu::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(input.value != 0)
|
||||
if((config->isMappedTo("b", input) || config->isMappedTo("menu", input)) && input.value != 0)
|
||||
{
|
||||
if(config->isMappedTo("b", input) || config->isMappedTo("menu", input))
|
||||
{
|
||||
Sound::getFromTheme(mTheme, "menu", "menuClose")->play();
|
||||
delete this;
|
||||
return true;
|
||||
}else if(config->isMappedTo("a", input) && mList.size() > 0)
|
||||
{
|
||||
mList.getSelected()();
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GuiComponent::input(config, input);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
#include "../components/TextListComponent.h"
|
||||
#include "../components/NinePatchComponent.h"
|
||||
#include "../components/MenuComponent.h"
|
||||
#include <functional>
|
||||
|
||||
class GuiMenu : public GuiComponent
|
||||
|
@ -13,7 +12,5 @@ public:
|
|||
bool input(InputConfig* config, Input input) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<ThemeData> mTheme;
|
||||
NinePatchComponent mBackground;
|
||||
TextListComponent< std::function<void()> > mList;
|
||||
MenuComponent mMenu;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#define SELECTED_SCALE 1.5f
|
||||
#define LOGO_PADDING ((logoSize().x() * (SELECTED_SCALE - 1)/2) + (mSize.x() * 0.06f))
|
||||
|
||||
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window)
|
||||
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP)
|
||||
{
|
||||
mCamOffset = 0;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "../../guis/GuiFastSelect.h"
|
||||
#include "../ViewController.h"
|
||||
#include "../../Settings.h"
|
||||
#include "../../Log.h"
|
||||
#include "../../Sound.h"
|
||||
|
||||
bool IGameListView::input(InputConfig* config, Input input)
|
||||
{
|
||||
|
@ -37,6 +39,7 @@ bool IGameListView::input(InputConfig* config, Input input)
|
|||
}else if(config->isMappedTo("select", input) && input.value != 0)
|
||||
{
|
||||
// open fast select
|
||||
Sound::getFromTheme(mTheme, getName(), "menuOpen")->play();
|
||||
mWindow->pushGui(new GuiFastSelect(mWindow, this));
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue