Merge pull request #235 from zigurana/KioskMode

Introducing Kiosk Mode, hiding certain menu items from the UI.
This commit is contained in:
Jools Wills 2017-09-28 18:55:14 +01:00 committed by GitHub
commit 99c1ddb260
10 changed files with 489 additions and 345 deletions

View file

@ -103,6 +103,9 @@ You can use `--help` or `-h` to view a list of command-line options. Briefly out
--windowed - run ES in a window, works best in conjunction with --resolution [w] [h]. --windowed - run ES in a window, works best in conjunction with --resolution [w] [h].
--vsync [1/on or 0/off] - turn vsync on or off (default is on). --vsync [1/on or 0/off] - turn vsync on or off (default is on).
--scrape - run the interactive command-line metadata scraper. --scrape - run the interactive command-line metadata scraper.
--no-splash - don't show the splash screen.
--max-vram [size] - Max VRAM to use in Mb before swapping. 0 for unlimited.
--force-kiosk - Force the UI mode to be Kiosk.
``` ```
As long as ES hasn't frozen, you can always press F4 to close the application. As long as ES hasn't frozen, you can always press F4 to close the application.

View file

@ -1,6 +1,7 @@
#include "GuiGamelistOptions.h" #include "GuiGamelistOptions.h"
#include "GuiMetaDataEd.h" #include "GuiMetaDataEd.h"
#include "Util.h" #include "Util.h"
#include "Settings.h"
#include "views/gamelist/IGameListView.h" #include "views/gamelist/IGameListView.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
@ -64,8 +65,10 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui
mMenu.addRow(row); mMenu.addRow(row);
std::map<std::string, CollectionSystemData> customCollections = CollectionSystemManager::get()->getCustomCollectionSystems(); std::map<std::string, CollectionSystemData> customCollections = CollectionSystemManager::get()->getCustomCollectionSystems();
if((customCollections.find(system->getName()) != customCollections.end() && CollectionSystemManager::get()->getEditingCollection() != system->getName()) ||
CollectionSystemManager::get()->getCustomCollectionsBundle()->getName() == system->getName()) if(ViewController::get()->isUIModeFull() &&
((customCollections.find(system->getName()) != customCollections.end() && CollectionSystemManager::get()->getEditingCollection() != system->getName()) ||
CollectionSystemManager::get()->getCustomCollectionsBundle()->getName() == system->getName()))
{ {
row.elements.clear(); row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "ADD/REMOVE GAMES TO THIS GAME COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(mWindow, "ADD/REMOVE GAMES TO THIS GAME COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
@ -73,7 +76,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui
mMenu.addRow(row); mMenu.addRow(row);
} }
if(CollectionSystemManager::get()->isEditing()) if(ViewController::get()->isUIModeFull() && CollectionSystemManager::get()->isEditing())
{ {
row.elements.clear(); row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "FINISH EDITING '" + strToUpper(CollectionSystemManager::get()->getEditingCollection()) + "' COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(mWindow, "FINISH EDITING '" + strToUpper(CollectionSystemManager::get()->getEditingCollection()) + "' COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
@ -81,8 +84,8 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui
mMenu.addRow(row); mMenu.addRow(row);
} }
if (!fromPlaceholder && !(mSystem->isCollection() && file->getType() == FOLDER)) { if (ViewController::get()->isUIModeFull() && !fromPlaceholder && !(mSystem->isCollection() && file->getType() == FOLDER))
{
row.elements.clear(); row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "EDIT THIS GAME'S METADATA", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(mWindow, "EDIT THIS GAME'S METADATA", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
row.addElement(makeArrow(mWindow), false); row.addElement(makeArrow(mWindow), false);

View file

@ -23,19 +23,36 @@
GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window) GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window)
{ {
// MAIN MENU bool isFullUI = ViewController::get()->isUIModeFull();
// SCRAPER > if (isFullUI)
// SOUND SETTINGS > addEntry("SCRAPER", 0x777777FF, true, [this] { openScraperSettings(); });
// UI SETTINGS >
// CONFIGURE INPUT >
// QUIT >
// [version] addEntry("SOUND SETTINGS", 0x777777FF, true, [this] { openSoundSettings(); });
auto openScrapeNow = [this] { mWindow->pushGui(new GuiScraperStart(mWindow)); };
addEntry("SCRAPER", 0x777777FF, true, if (isFullUI)
[this, openScrapeNow] { addEntry("UI SETTINGS", 0x777777FF, true, [this] { openUISettings(); });
if (isFullUI)
addEntry("GAME COLLECTION SETTINGS", 0x777777FF, true, [this] { openCollectionSystemSettings(); });
if (isFullUI)
addEntry("OTHER SETTINGS", 0x777777FF, true, [this] { openOtherSettings(); });
if (isFullUI)
addEntry("CONFIGURE INPUT", 0x777777FF, true, [this] { openConfigInput(); });
addEntry("QUIT", 0x777777FF, true, [this] {openQuitMenu(); });
addChild(&mMenu);
addVersionInfo();
setSize(mMenu.getSize());
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, Renderer::getScreenHeight() * 0.15f);
}
void GuiMenu::openScraperSettings()
{
auto s = new GuiSettings(mWindow, "SCRAPER"); auto s = new GuiSettings(mWindow, "SCRAPER");
// scrape from // scrape from
@ -55,6 +72,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
// scrape now // scrape now
ComponentListRow row; ComponentListRow row;
auto openScrapeNow = [this] { mWindow->pushGui(new GuiScraperStart(mWindow)); };
std::function<void()> openAndSave = openScrapeNow; std::function<void()> openAndSave = openScrapeNow;
openAndSave = [s, openAndSave] { s->save(); openAndSave(); }; openAndSave = [s, openAndSave] { s->save(); openAndSave(); };
row.makeAcceptInputHandler(openAndSave); row.makeAcceptInputHandler(openAndSave);
@ -66,10 +84,10 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
s->addRow(row); s->addRow(row);
mWindow->pushGui(s); mWindow->pushGui(s);
}); }
addEntry("SOUND SETTINGS", 0x777777FF, true, void GuiMenu::openSoundSettings()
[this] { {
auto s = new GuiSettings(mWindow, "SOUND SETTINGS"); auto s = new GuiSettings(mWindow, "SOUND SETTINGS");
// volume // volume
@ -78,7 +96,9 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
s->addWithLabel("SYSTEM VOLUME", volume); s->addWithLabel("SYSTEM VOLUME", volume);
s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)round(volume->getValue())); }); s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)round(volume->getValue())); });
#ifdef _RPI_ if (ViewController::get()->isUIModeFull())
{
#ifdef _RPI_
// volume control device // volume control device
auto vol_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "AUDIO DEVICE", false); auto vol_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "AUDIO DEVICE", false);
std::vector<std::string> transitions; std::vector<std::string> transitions;
@ -93,7 +113,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
VolumeControl::getInstance()->deinit(); VolumeControl::getInstance()->deinit();
VolumeControl::getInstance()->init(); VolumeControl::getInstance()->init();
}); });
#endif #endif
// disable sounds // disable sounds
auto sounds_enabled = std::make_shared<SwitchComponent>(mWindow); auto sounds_enabled = std::make_shared<SwitchComponent>(mWindow);
@ -124,14 +144,30 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
Settings::getInstance()->setString("OMXAudioDev", omx_audio_dev->getSelected()); Settings::getInstance()->setString("OMXAudioDev", omx_audio_dev->getSelected());
}); });
#endif #endif
}
mWindow->pushGui(s); mWindow->pushGui(s);
});
addEntry("UI SETTINGS", 0x777777FF, true, }
[this] {
void GuiMenu::openUISettings()
{
auto s = new GuiSettings(mWindow, "UI SETTINGS"); auto s = new GuiSettings(mWindow, "UI SETTINGS");
//UI mode
auto UImodeSelection = std::make_shared< OptionListComponent<std::string> >(mWindow, "UI MODE", false);
std::vector<std::string> UImodes = ViewController::get()->getUIModes();
for (auto it = UImodes.begin(); it != UImodes.end(); it++)
UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it);
s->addWithLabel("UI MODE", UImodeSelection);
Window* window = mWindow;
s->addSaveFunc([UImodeSelection, window]
{
LOG(LogDebug) << "Setting UI mode to" << UImodeSelection->getSelected();
Settings::getInstance()->setString("UIMode", UImodeSelection->getSelected());
});
// screensaver
ComponentListRow screensaver_row; ComponentListRow screensaver_row;
screensaver_row.elements.clear(); screensaver_row.elements.clear();
screensaver_row.addElement(std::make_shared<TextComponent>(mWindow, "SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); screensaver_row.addElement(std::make_shared<TextComponent>(mWindow, "SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
@ -237,14 +273,11 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
s->addSaveFunc([show_help] { Settings::getInstance()->setBool("ShowHelpPrompts", show_help->getState()); }); s->addSaveFunc([show_help] { Settings::getInstance()->setBool("ShowHelpPrompts", show_help->getState()); });
mWindow->pushGui(s); mWindow->pushGui(s);
});
addEntry("GAME COLLECTION SETTINGS", 0x777777FF, true, }
[this] { openCollectionSystemSettings();
});
addEntry("OTHER SETTINGS", 0x777777FF, true, void GuiMenu::openOtherSettings()
[this] { {
auto s = new GuiSettings(mWindow, "OTHER SETTINGS"); auto s = new GuiSettings(mWindow, "OTHER SETTINGS");
// maximum vram // maximum vram
@ -319,25 +352,29 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
mWindow->pushGui(s); mWindow->pushGui(s);
});
addEntry("CONFIGURE INPUT", 0x777777FF, true, }
[this] {
void GuiMenu::openConfigInput()
{
Window* window = mWindow; Window* window = mWindow;
window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES",
[window] { [window] {
window->pushGui(new GuiDetectDevice(window, false, nullptr)); window->pushGui(new GuiDetectDevice(window, false, nullptr));
}, "NO", nullptr) }, "NO", nullptr)
); );
});
addEntry("QUIT", 0x777777FF, true, }
[this] {
void GuiMenu::openQuitMenu()
{
auto s = new GuiSettings(mWindow, "QUIT"); auto s = new GuiSettings(mWindow, "QUIT");
Window* window = mWindow; Window* window = mWindow;
ComponentListRow row; ComponentListRow row;
if (ViewController::get()->isUIModeFull())
{
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
[] { [] {
@ -348,6 +385,24 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
row.addElement(std::make_shared<TextComponent>(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(std::make_shared<TextComponent>(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row); s->addRow(row);
if(Settings::getInstance()->getBool("ShowExit"))
{
row.elements.clear();
row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES",
[] {
SDL_Event ev;
ev.type = SDL_QUIT;
SDL_PushEvent(&ev);
}, "NO", nullptr));
});
row.addElement(std::make_shared<TextComponent>(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row);
}
}
row.elements.clear(); row.elements.clear();
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
@ -363,41 +418,24 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES", window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES",
[] { [] {
if(quitES("/tmp/es-shutdown") != 0) if (quitES("/tmp/es-shutdown") != 0)
LOG(LogWarning) << "Shutdown terminated with non-zero result!"; LOG(LogWarning) << "Shutdown terminated with non-zero result!";
}, "NO", nullptr)); }, "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);
if(Settings::getInstance()->getBool("ShowExit"))
{
row.elements.clear();
row.makeAcceptInputHandler([window] {
window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES",
[] {
SDL_Event ev;
ev.type = SDL_QUIT;
SDL_PushEvent(&ev);
}, "NO", nullptr));
});
row.addElement(std::make_shared<TextComponent>(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addRow(row);
}
mWindow->pushGui(s); mWindow->pushGui(s);
}); }
void GuiMenu::addVersionInfo()
{
mVersion.setFont(Font::get(FONT_SIZE_SMALL)); mVersion.setFont(Font::get(FONT_SIZE_SMALL));
mVersion.setColor(0x5E5E5EFF); mVersion.setColor(0x5E5E5EFF);
mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING)); mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING));
mVersion.setHorizontalAlignment(ALIGN_CENTER); mVersion.setHorizontalAlignment(ALIGN_CENTER);
addChild(&mMenu);
addChild(&mVersion); addChild(&mVersion);
setSize(mMenu.getSize());
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, Renderer::getScreenHeight() * 0.15f);
} }
void GuiMenu::openScreensaverOptions() { void GuiMenu::openScreensaverOptions() {

View file

@ -16,8 +16,16 @@ public:
private: private:
void addEntry(const char* name, unsigned int color, bool add_arrow, const std::function<void()>& func); void addEntry(const char* name, unsigned int color, bool add_arrow, const std::function<void()>& func);
void openScreensaverOptions(); void addVersionInfo();
void openCollectionSystemSettings(); void openCollectionSystemSettings();
void openConfigInput();
void openOtherSettings();
void openQuitMenu();
void openScraperSettings();
void openScreensaverOptions();
void openSoundSettings();
void openUISettings();
MenuComponent mMenu; MenuComponent mMenu;
TextComponent mVersion; TextComponent mVersion;
}; };

View file

@ -85,6 +85,10 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height
{ {
int maxVRAM = atoi(argv[i + 1]); int maxVRAM = atoi(argv[i + 1]);
Settings::getInstance()->setInt("MaxVRAM", maxVRAM); Settings::getInstance()->setInt("MaxVRAM", maxVRAM);
}
else if (strcmp(argv[i], "--force-kiosk") == 0)
{
Settings::getInstance()->setBool("ForceKiosk", true);
}else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) }else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
{ {
#ifdef WIN32 #ifdef WIN32
@ -111,6 +115,7 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height
"--windowed not fullscreen, should be used with --resolution\n" "--windowed not fullscreen, should be used with --resolution\n"
"--vsync [1/on or 0/off] turn vsync on or off (default is on)\n" "--vsync [1/on or 0/off] turn vsync on or off (default is on)\n"
"--max-vram [size] Max VRAM to use in Mb before swapping. 0 for unlimited\n" "--max-vram [size] Max VRAM to use in Mb before swapping. 0 for unlimited\n"
"--force-kiosk Force the UI mode to be Kiosk\n"
"--help, -h summon a sentient, angry tuba\n\n" "--help, -h summon a sentient, angry tuba\n\n"
"More information available in README.md.\n"; "More information available in README.md.\n";
return false; //exit after printing help return false; //exit after printing help

View file

@ -33,6 +33,7 @@ ViewController::ViewController(Window* window)
: GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(0), mLockInput(false) : GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(0), mLockInput(false)
{ {
mState.viewing = NOTHING; mState.viewing = NOTHING;
mCurUIMode = Settings::getInstance()->getString("UIMode");
} }
ViewController::~ViewController() ViewController::~ViewController()
@ -43,10 +44,6 @@ ViewController::~ViewController()
void ViewController::goToStart() void ViewController::goToStart()
{ {
// TODO
/* mState.viewing = START_SCREEN;
mCurrentView.reset();
playViewTransition(); */
goToSystemView(SystemData::sSystemVector.at(0)); goToSystemView(SystemData::sSystemVector.at(0));
} }
@ -399,6 +396,9 @@ void ViewController::render(const Eigen::Affine3f& parentTrans)
Eigen::Vector3f viewStart = trans.inverse().translation(); Eigen::Vector3f viewStart = trans.inverse().translation();
Eigen::Vector3f viewEnd = trans.inverse() * Eigen::Vector3f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight(), 0); Eigen::Vector3f viewEnd = trans.inverse() * Eigen::Vector3f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight(), 0);
// Keep track of UI mode changes.
monitorUIMode();
// draw systemview // draw systemview
getSystemListView()->render(trans); getSystemListView()->render(trans);
@ -499,6 +499,22 @@ void ViewController::reloadAll()
updateHelpPrompts(); updateHelpPrompts();
} }
void ViewController::monitorUIMode()
{
std::string uimode = Settings::getInstance()->getString("UIMode");
if (uimode != mCurUIMode) // UIMODE HAS CHANGED
{
mCurUIMode = uimode;
reloadAll();
goToStart();
}
}
bool ViewController::isUIModeFull()
{
return ((mCurUIMode == "Full") && ! Settings::getInstance()->getBool("ForceKiosk"));
}
std::vector<HelpPrompt> ViewController::getHelpPrompts() std::vector<HelpPrompt> ViewController::getHelpPrompts()
{ {
std::vector<HelpPrompt> prompts; std::vector<HelpPrompt> prompts;

View file

@ -5,6 +5,8 @@
class SystemData; class SystemData;
const std::vector<std::string> UIModes = { "Full", "Kiosk" };
// Used to smoothly transition the camera between multiple views (e.g. from system to system, from gamelist to gamelist). // Used to smoothly transition the camera between multiple views (e.g. from system to system, from gamelist to gamelist).
class ViewController : public GuiComponent class ViewController : public GuiComponent
{ {
@ -24,6 +26,10 @@ public:
inline void reloadGameListView(SystemData* system, bool reloadTheme = false) { reloadGameListView(getGameListView(system).get(), reloadTheme); } inline void reloadGameListView(SystemData* system, bool reloadTheme = false) { reloadGameListView(getGameListView(system).get(), reloadTheme); }
void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes. void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes.
void monitorUIMode();
bool isUIModeFull();
inline std::vector<std::string> getUIModes() { return UIModes; };
// Navigation. // Navigation.
void goToNextGameList(); void goToNextGameList();
void goToPrevGameList(); void goToPrevGameList();
@ -95,4 +101,5 @@ private:
bool mLockInput; bool mLockInput;
State mState; State mState;
std::string mCurUIMode;
}; };

View file

@ -13,12 +13,13 @@ std::vector<const char*> settings_dont_save = boost::assign::list_of
("Debug") ("Debug")
("DebugGrid") ("DebugGrid")
("DebugText") ("DebugText")
("ShowExit") ("ForceKiosk")
("Windowed")
("VSync")
("HideConsole")
("IgnoreGamelist") ("IgnoreGamelist")
("SplashScreen"); ("HideConsole")
("ShowExit")
("SplashScreen")
("VSync")
("Windowed");
Settings::Settings() Settings::Settings()
{ {
@ -124,6 +125,9 @@ void Settings::setDefaults()
mStringMap["AudioDevice"] = "Master"; mStringMap["AudioDevice"] = "Master";
#endif #endif
mStringMap["UIMode"] = "Full";
mStringMap["UIMode_passkey"] = "uuddlrlrba";
mBoolMap["ForceKiosk"] = false;
} }
template <typename K, typename V> template <typename K, typename V>

View file

@ -14,6 +14,7 @@ Window::Window() : mNormalizeNextUpdate(false), mFrameTimeElapsed(0), mFrameCoun
{ {
mHelp = new HelpComponent(this); mHelp = new HelpComponent(this);
mBackgroundOverlay = new ImageComponent(this); mBackgroundOverlay = new ImageComponent(this);
mPassKeyListener = new PassKeyListener;
} }
Window::~Window() Window::~Window()
@ -170,8 +171,11 @@ void Window::input(InputConfig* config, Input input)
} }
else else
{ {
if(peekGui()) if (!mPassKeyListener->isUIModeChanged(config, input, this) && // check if UI mode has changed due to passphrase completion
this->peekGui()->input(config, input); peekGui())
{
this->peekGui()->input(config, input); // this is where the majority of inputs will be consumed: the GuiComponent Stack
}
} }
} }
@ -435,3 +439,43 @@ void Window::startScreenSaver()
mScreenSaver->renderScreenSaver(); mScreenSaver->renderScreenSaver();
} }
bool Window::PassKeyListener::isUIModeChanged(InputConfig * config, Input input, Window* window)
{
// This function reads the current input to listen for the passkey
// sequence to unlock the UI mode. The progress is saved in mPassKeyCounter
// supported sequence-inputs: u (up), d (down), l (left), r (right), a, b, x, y
// default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'.
if ((Settings::getInstance()->getString("UIMode") == "Full") || (!input.value))
{
return false; // Already unlocked, or no keydown, nothing to do here.
}
bool foundMatch = false;
for (auto valstring : mInputVals)
{
if (config->isMappedTo(valstring, input) &&
(this->mPassKeySequence[this->mPassKeyCounter] == valstring[0]))
{
this->mPassKeyCounter ++;
foundMatch = true;
}
}
if (!foundMatch)
{
this->mPassKeyCounter = 0; // current input is incorrect, reset counter
}
if (this->mPassKeyCounter == (this->mPassKeySequence.length()))
{
// When we have reached the end of the list, trigger UI_mode unlock
LOG(LogDebug) << " Window::PassKeyListener::isUIModeChanged(): Passkey sequence completed, switching UIMode to full";
Settings::getInstance()->setString("UIMode", "Full");
Settings::getInstance()->saveFile();
this->mPassKeyCounter = 0;
return true;
}
return false;
}

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "GuiComponent.h" #include "GuiComponent.h"
#include "InputManager.h"
#include "Settings.h"
#include <vector> #include <vector>
#include "resources/Font.h" #include "resources/Font.h"
#include "InputManager.h"
class FileData; class FileData;
class HelpComponent; class HelpComponent;
@ -32,6 +33,20 @@ public:
virtual ~InfoPopup() {}; virtual ~InfoPopup() {};
}; };
class PassKeyListener {
public:
bool isUIModeChanged(InputConfig* config, Input input, Window* window);
PassKeyListener()
{
mPassKeySequence = Settings::getInstance()->getString("UIMode_passkey");
mPassKeyCounter = 0;
}
private:
std::string mPassKeySequence;
int mPassKeyCounter;
const std::vector<std::string> mInputVals = { "up", "down", "left", "right", "a", "b", "x", "y" };
};
Window(); Window();
~Window(); ~Window();
@ -79,6 +94,7 @@ private:
ScreenSaver* mScreenSaver; ScreenSaver* mScreenSaver;
InfoPopup* mInfoPopup; InfoPopup* mInfoPopup;
bool mRenderScreenSaver; bool mRenderScreenSaver;
PassKeyListener* mPassKeyListener;
std::vector<GuiComponent*> mGuiStack; std::vector<GuiComponent*> mGuiStack;