1 #include "guis/GuiMenu.h"
2
3 #include "components/OptionListComponent.h"
4 #include "components/SliderComponent.h"
5 #include "components/SwitchComponent.h"
6 #include "guis/GuiCollectionSystemsOptions.h"
7 #include "guis/GuiDetectDevice.h"
8 #include "guis/GuiGeneralScreensaverOptions.h"
9 #include "guis/GuiMsgBox.h"
10 #include "guis/GuiScraperStart.h"
11 #include "guis/GuiSettings.h"
12 #include "views/UIModeController.h"
13 #include "views/ViewController.h"
14 #include "CollectionSystemManager.h"
15 #include "EmulationStation.h"
16 #include "Scripting.h"
17 #include "SystemData.h"
18 #include "VolumeControl.h"
19 #include <SDL_events.h>
20 #include <algorithm>
21 #include "platform.h"
22
GuiMenu(Window * window)23 GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window)
24 {
25 bool isFullUI = UIModeController::getInstance()->isUIModeFull();
26
27 if (isFullUI)
28 addEntry("SCRAPER", 0x777777FF, true, [this] { openScraperSettings(); });
29
30 addEntry("SOUND SETTINGS", 0x777777FF, true, [this] { openSoundSettings(); });
31
32
33 if (isFullUI)
34 addEntry("UI SETTINGS", 0x777777FF, true, [this] { openUISettings(); });
35
36 if (isFullUI)
37 addEntry("GAME COLLECTION SETTINGS", 0x777777FF, true, [this] { openCollectionSystemSettings(); });
38
39 if (isFullUI)
40 addEntry("OTHER SETTINGS", 0x777777FF, true, [this] { openOtherSettings(); });
41
42 if (isFullUI)
43 addEntry("CONFIGURE INPUT", 0x777777FF, true, [this] { openConfigInput(); });
44
45 addEntry("QUIT", 0x777777FF, true, [this] {openQuitMenu(); });
46
47 addChild(&mMenu);
48 addVersionInfo();
49 setSize(mMenu.getSize());
50 setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, Renderer::getScreenHeight() * 0.15f);
51 }
52
openScraperSettings()53 void GuiMenu::openScraperSettings()
54 {
55 auto s = new GuiSettings(mWindow, "SCRAPER");
56
57 // scrape from
58 auto scraper_list = std::make_shared< OptionListComponent< std::string > >(mWindow, "SCRAPE FROM", false);
59 std::vector<std::string> scrapers = getScraperList();
60
61 // Select either the first entry of the one read from the settings, just in case the scraper from settings has vanished.
62 for(auto it = scrapers.cbegin(); it != scrapers.cend(); it++)
63 scraper_list->add(*it, *it, *it == Settings::getInstance()->getString("Scraper"));
64
65 s->addWithLabel("SCRAPE FROM", scraper_list);
66 s->addSaveFunc([scraper_list] { Settings::getInstance()->setString("Scraper", scraper_list->getSelected()); });
67
68 // scrape ratings
69 auto scrape_ratings = std::make_shared<SwitchComponent>(mWindow);
70 scrape_ratings->setState(Settings::getInstance()->getBool("ScrapeRatings"));
71 s->addWithLabel("SCRAPE RATINGS", scrape_ratings);
72 s->addSaveFunc([scrape_ratings] { Settings::getInstance()->setBool("ScrapeRatings", scrape_ratings->getState()); });
73
74 // scrape now
75 ComponentListRow row;
76 auto openScrapeNow = [this] { mWindow->pushGui(new GuiScraperStart(mWindow)); };
77 std::function<void()> openAndSave = openScrapeNow;
78 openAndSave = [s, openAndSave] { s->save(); openAndSave(); };
79 row.makeAcceptInputHandler(openAndSave);
80
81 auto scrape_now = std::make_shared<TextComponent>(mWindow, "SCRAPE NOW", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
82 auto bracket = makeArrow(mWindow);
83 row.addElement(scrape_now, true);
84 row.addElement(bracket, false);
85 s->addRow(row);
86
87 mWindow->pushGui(s);
88 }
89
openSoundSettings()90 void GuiMenu::openSoundSettings()
91 {
92 auto s = new GuiSettings(mWindow, "SOUND SETTINGS");
93
94 // volume
95 auto volume = std::make_shared<SliderComponent>(mWindow, 0.f, 100.f, 1.f, "%");
96 volume->setValue((float)VolumeControl::getInstance()->getVolume());
97 s->addWithLabel("SYSTEM VOLUME", volume);
98 s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)Math::round(volume->getValue())); });
99
100 if (UIModeController::getInstance()->isUIModeFull())
101 {
102 #if defined(__linux__)
103 // audio card
104 auto audio_card = std::make_shared< OptionListComponent<std::string> >(mWindow, "AUDIO CARD", false);
105 std::vector<std::string> audio_cards;
106 audio_cards.push_back("default");
107 audio_cards.push_back("sysdefault");
108 audio_cards.push_back("dmix");
109 audio_cards.push_back("hw");
110 audio_cards.push_back("plughw");
111 audio_cards.push_back("null");
112 if (Settings::getInstance()->getString("AudioCard") != "") {
113 if(std::find(audio_cards.begin(), audio_cards.end(), Settings::getInstance()->getString("AudioCard")) == audio_cards.end()) {
114 audio_cards.push_back(Settings::getInstance()->getString("AudioCard"));
115 }
116 }
117 for(auto ac = audio_cards.cbegin(); ac != audio_cards.cend(); ac++)
118 audio_card->add(*ac, *ac, Settings::getInstance()->getString("AudioCard") == *ac);
119 s->addWithLabel("AUDIO CARD", audio_card);
120 s->addSaveFunc([audio_card] {
121 Settings::getInstance()->setString("AudioCard", audio_card->getSelected());
122 VolumeControl::getInstance()->deinit();
123 VolumeControl::getInstance()->init();
124 });
125
126 // volume control device
127 auto vol_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "AUDIO DEVICE", false);
128 std::vector<std::string> transitions;
129 transitions.push_back("PCM");
130 transitions.push_back("HDMI");
131 transitions.push_back("Headphone");
132 transitions.push_back("Speaker");
133 transitions.push_back("Master");
134 transitions.push_back("Digital");
135 transitions.push_back("Analogue");
136 if (Settings::getInstance()->getString("AudioDevice") != "") {
137 if(std::find(transitions.begin(), transitions.end(), Settings::getInstance()->getString("AudioDevice")) == transitions.end()) {
138 transitions.push_back(Settings::getInstance()->getString("AudioDevice"));
139 }
140 }
141 for(auto it = transitions.cbegin(); it != transitions.cend(); it++)
142 vol_dev->add(*it, *it, Settings::getInstance()->getString("AudioDevice") == *it);
143 s->addWithLabel("AUDIO DEVICE", vol_dev);
144 s->addSaveFunc([vol_dev] {
145 Settings::getInstance()->setString("AudioDevice", vol_dev->getSelected());
146 VolumeControl::getInstance()->deinit();
147 VolumeControl::getInstance()->init();
148 });
149 #endif
150
151 // disable sounds
152 auto sounds_enabled = std::make_shared<SwitchComponent>(mWindow);
153 sounds_enabled->setState(Settings::getInstance()->getBool("EnableSounds"));
154 s->addWithLabel("ENABLE NAVIGATION SOUNDS", sounds_enabled);
155 s->addSaveFunc([sounds_enabled] {
156 if (sounds_enabled->getState()
157 && !Settings::getInstance()->getBool("EnableSounds")
158 && PowerSaver::getMode() == PowerSaver::INSTANT)
159 {
160 Settings::getInstance()->setString("PowerSaverMode", "default");
161 PowerSaver::init();
162 }
163 Settings::getInstance()->setBool("EnableSounds", sounds_enabled->getState());
164 });
165
166 auto video_audio = std::make_shared<SwitchComponent>(mWindow);
167 video_audio->setState(Settings::getInstance()->getBool("VideoAudio"));
168 s->addWithLabel("ENABLE VIDEO AUDIO", video_audio);
169 s->addSaveFunc([video_audio] { Settings::getInstance()->setBool("VideoAudio", video_audio->getState()); });
170
171 #ifdef _RPI_
172 // OMX player Audio Device
173 auto omx_audio_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "OMX PLAYER AUDIO DEVICE", false);
174 std::vector<std::string> omx_cards;
175 // RPi Specific Audio Cards
176 omx_cards.push_back("local");
177 omx_cards.push_back("hdmi");
178 omx_cards.push_back("both");
179 omx_cards.push_back("alsa");
180 omx_cards.push_back("alsa:hw:0,0");
181 omx_cards.push_back("alsa:hw:1,0");
182 if (Settings::getInstance()->getString("OMXAudioDev") != "") {
183 if (std::find(omx_cards.begin(), omx_cards.end(), Settings::getInstance()->getString("OMXAudioDev")) == omx_cards.end()) {
184 omx_cards.push_back(Settings::getInstance()->getString("OMXAudioDev"));
185 }
186 }
187 for (auto it = omx_cards.cbegin(); it != omx_cards.cend(); it++)
188 omx_audio_dev->add(*it, *it, Settings::getInstance()->getString("OMXAudioDev") == *it);
189 s->addWithLabel("OMX PLAYER AUDIO DEVICE", omx_audio_dev);
190 s->addSaveFunc([omx_audio_dev] {
191 if (Settings::getInstance()->getString("OMXAudioDev") != omx_audio_dev->getSelected())
192 Settings::getInstance()->setString("OMXAudioDev", omx_audio_dev->getSelected());
193 });
194 #endif
195 }
196
197 mWindow->pushGui(s);
198
199 }
200
openUISettings()201 void GuiMenu::openUISettings()
202 {
203 auto s = new GuiSettings(mWindow, "UI SETTINGS");
204
205 //UI mode
206 auto UImodeSelection = std::make_shared< OptionListComponent<std::string> >(mWindow, "UI MODE", false);
207 std::vector<std::string> UImodes = UIModeController::getInstance()->getUIModes();
208 for (auto it = UImodes.cbegin(); it != UImodes.cend(); it++)
209 UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it);
210 s->addWithLabel("UI MODE", UImodeSelection);
211 Window* window = mWindow;
212 s->addSaveFunc([ UImodeSelection, window]
213 {
214 std::string selectedMode = UImodeSelection->getSelected();
215 if (selectedMode != "Full")
216 {
217 std::string msg = "You are changing the UI to a restricted mode:\n" + selectedMode + "\n";
218 msg += "This will hide most menu-options to prevent changes to the system.\n";
219 msg += "To unlock and return to the full UI, enter this code: \n";
220 msg += "\"" + UIModeController::getInstance()->getFormattedPassKeyStr() + "\"\n\n";
221 msg += "Do you want to proceed?";
222 window->pushGui(new GuiMsgBox(window, msg,
223 "YES", [selectedMode] {
224 LOG(LogDebug) << "Setting UI mode to " << selectedMode;
225 Settings::getInstance()->setString("UIMode", selectedMode);
226 Settings::getInstance()->saveFile();
227 }, "NO",nullptr));
228 }
229 });
230
231 // screensaver
232 ComponentListRow screensaver_row;
233 screensaver_row.elements.clear();
234 screensaver_row.addElement(std::make_shared<TextComponent>(mWindow, "SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
235 screensaver_row.addElement(makeArrow(mWindow), false);
236 screensaver_row.makeAcceptInputHandler(std::bind(&GuiMenu::openScreensaverOptions, this));
237 s->addRow(screensaver_row);
238
239 // quick system select (left/right in game list view)
240 auto quick_sys_select = std::make_shared<SwitchComponent>(mWindow);
241 quick_sys_select->setState(Settings::getInstance()->getBool("QuickSystemSelect"));
242 s->addWithLabel("QUICK SYSTEM SELECT", quick_sys_select);
243 s->addSaveFunc([quick_sys_select] { Settings::getInstance()->setBool("QuickSystemSelect", quick_sys_select->getState()); });
244
245 // carousel transition option
246 auto move_carousel = std::make_shared<SwitchComponent>(mWindow);
247 move_carousel->setState(Settings::getInstance()->getBool("MoveCarousel"));
248 s->addWithLabel("CAROUSEL TRANSITIONS", move_carousel);
249 s->addSaveFunc([move_carousel] {
250 if (move_carousel->getState()
251 && !Settings::getInstance()->getBool("MoveCarousel")
252 && PowerSaver::getMode() == PowerSaver::INSTANT)
253 {
254 Settings::getInstance()->setString("PowerSaverMode", "default");
255 PowerSaver::init();
256 }
257 Settings::getInstance()->setBool("MoveCarousel", move_carousel->getState());
258 });
259
260 // transition style
261 auto transition_style = std::make_shared< OptionListComponent<std::string> >(mWindow, "TRANSITION STYLE", false);
262 std::vector<std::string> transitions;
263 transitions.push_back("fade");
264 transitions.push_back("slide");
265 transitions.push_back("instant");
266 for(auto it = transitions.cbegin(); it != transitions.cend(); it++)
267 transition_style->add(*it, *it, Settings::getInstance()->getString("TransitionStyle") == *it);
268 s->addWithLabel("TRANSITION STYLE", transition_style);
269 s->addSaveFunc([transition_style] {
270 if (Settings::getInstance()->getString("TransitionStyle") == "instant"
271 && transition_style->getSelected() != "instant"
272 && PowerSaver::getMode() == PowerSaver::INSTANT)
273 {
274 Settings::getInstance()->setString("PowerSaverMode", "default");
275 PowerSaver::init();
276 }
277 Settings::getInstance()->setString("TransitionStyle", transition_style->getSelected());
278 });
279
280 // theme set
281 auto themeSets = ThemeData::getThemeSets();
282
283 if(!themeSets.empty())
284 {
285 std::map<std::string, ThemeSet>::const_iterator selectedSet = themeSets.find(Settings::getInstance()->getString("ThemeSet"));
286 if(selectedSet == themeSets.cend())
287 selectedSet = themeSets.cbegin();
288
289 auto theme_set = std::make_shared< OptionListComponent<std::string> >(mWindow, "THEME SET", false);
290 for(auto it = themeSets.cbegin(); it != themeSets.cend(); it++)
291 theme_set->add(it->first, it->first, it == selectedSet);
292 s->addWithLabel("THEME SET", theme_set);
293
294 Window* window = mWindow;
295 s->addSaveFunc([window, theme_set]
296 {
297 bool needReload = false;
298 std::string oldTheme = Settings::getInstance()->getString("ThemeSet");
299 if(oldTheme != theme_set->getSelected())
300 needReload = true;
301
302 Settings::getInstance()->setString("ThemeSet", theme_set->getSelected());
303
304 if(needReload)
305 {
306 Scripting::fireEvent("theme-changed", theme_set->getSelected(), oldTheme);
307 CollectionSystemManager::get()->updateSystemsList();
308 ViewController::get()->goToStart();
309 ViewController::get()->reloadAll(); // TODO - replace this with some sort of signal-based implementation
310 }
311 });
312 }
313
314 // GameList view style
315 auto gamelist_style = std::make_shared< OptionListComponent<std::string> >(mWindow, "GAMELIST VIEW STYLE", false);
316 std::vector<std::string> styles;
317 styles.push_back("automatic");
318 styles.push_back("basic");
319 styles.push_back("detailed");
320 styles.push_back("video");
321 styles.push_back("grid");
322
323 for (auto it = styles.cbegin(); it != styles.cend(); it++)
324 gamelist_style->add(*it, *it, Settings::getInstance()->getString("GamelistViewStyle") == *it);
325 s->addWithLabel("GAMELIST VIEW STYLE", gamelist_style);
326 s->addSaveFunc([gamelist_style] {
327 bool needReload = false;
328 if (Settings::getInstance()->getString("GamelistViewStyle") != gamelist_style->getSelected())
329 needReload = true;
330 Settings::getInstance()->setString("GamelistViewStyle", gamelist_style->getSelected());
331 if (needReload)
332 ViewController::get()->reloadAll();
333 });
334
335 // Optionally start in selected system
336 auto systemfocus_list = std::make_shared< OptionListComponent<std::string> >(mWindow, "START ON SYSTEM", false);
337 systemfocus_list->add("NONE", "", Settings::getInstance()->getString("StartupSystem") == "");
338 for (auto it = SystemData::sSystemVector.cbegin(); it != SystemData::sSystemVector.cend(); it++)
339 {
340 if ("retropie" != (*it)->getName())
341 {
342 systemfocus_list->add((*it)->getName(), (*it)->getName(), Settings::getInstance()->getString("StartupSystem") == (*it)->getName());
343 }
344 }
345 s->addWithLabel("START ON SYSTEM", systemfocus_list);
346 s->addSaveFunc([systemfocus_list] {
347 Settings::getInstance()->setString("StartupSystem", systemfocus_list->getSelected());
348 });
349
350 // show help
351 auto show_help = std::make_shared<SwitchComponent>(mWindow);
352 show_help->setState(Settings::getInstance()->getBool("ShowHelpPrompts"));
353 s->addWithLabel("ON-SCREEN HELP", show_help);
354 s->addSaveFunc([show_help] { Settings::getInstance()->setBool("ShowHelpPrompts", show_help->getState()); });
355
356 // enable filters (ForceDisableFilters)
357 auto enable_filter = std::make_shared<SwitchComponent>(mWindow);
358 enable_filter->setState(!Settings::getInstance()->getBool("ForceDisableFilters"));
359 s->addWithLabel("ENABLE FILTERS", enable_filter);
360 s->addSaveFunc([enable_filter] {
361 bool filter_is_enabled = !Settings::getInstance()->getBool("ForceDisableFilters");
362 Settings::getInstance()->setBool("ForceDisableFilters", !enable_filter->getState());
363 if (enable_filter->getState() != filter_is_enabled) ViewController::get()->ReloadAndGoToStart();
364 });
365
366 // hide start menu in Kid Mode
367 auto disable_start = std::make_shared<SwitchComponent>(mWindow);
368 disable_start->setState(Settings::getInstance()->getBool("DisableKidStartMenu"));
369 s->addWithLabel("DISABLE START MENU IN KID MODE", disable_start);
370 s->addSaveFunc([disable_start] { Settings::getInstance()->setBool("DisableKidStartMenu", disable_start->getState()); });
371
372 mWindow->pushGui(s);
373
374 }
375
openOtherSettings()376 void GuiMenu::openOtherSettings()
377 {
378 auto s = new GuiSettings(mWindow, "OTHER SETTINGS");
379
380 // maximum vram
381 auto max_vram = std::make_shared<SliderComponent>(mWindow, 0.f, 1000.f, 10.f, "Mb");
382 max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM")));
383 s->addWithLabel("VRAM LIMIT", max_vram);
384 s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)Math::round(max_vram->getValue())); });
385
386 // power saver
387 auto power_saver = std::make_shared< OptionListComponent<std::string> >(mWindow, "POWER SAVER MODES", false);
388 std::vector<std::string> modes;
389 modes.push_back("disabled");
390 modes.push_back("default");
391 modes.push_back("enhanced");
392 modes.push_back("instant");
393 for (auto it = modes.cbegin(); it != modes.cend(); it++)
394 power_saver->add(*it, *it, Settings::getInstance()->getString("PowerSaverMode") == *it);
395 s->addWithLabel("POWER SAVER MODES", power_saver);
396 s->addSaveFunc([this, power_saver] {
397 if (Settings::getInstance()->getString("PowerSaverMode") != "instant" && power_saver->getSelected() == "instant") {
398 Settings::getInstance()->setString("TransitionStyle", "instant");
399 Settings::getInstance()->setBool("MoveCarousel", false);
400 Settings::getInstance()->setBool("EnableSounds", false);
401 }
402 Settings::getInstance()->setString("PowerSaverMode", power_saver->getSelected());
403 PowerSaver::init();
404 });
405
406 // gamelists
407 auto gamelistsSaveMode = std::make_shared< OptionListComponent<std::string> >(mWindow, "SAVE METADATA", false);
408 std::vector<std::string> saveModes;
409 saveModes.push_back("on exit");
410 saveModes.push_back("always");
411 saveModes.push_back("never");
412
413 for(auto it = saveModes.cbegin(); it != saveModes.cend(); it++)
414 gamelistsSaveMode->add(*it, *it, Settings::getInstance()->getString("SaveGamelistsMode") == *it);
415 s->addWithLabel("SAVE METADATA", gamelistsSaveMode);
416 s->addSaveFunc([gamelistsSaveMode] {
417 Settings::getInstance()->setString("SaveGamelistsMode", gamelistsSaveMode->getSelected());
418 });
419
420 auto parse_gamelists = std::make_shared<SwitchComponent>(mWindow);
421 parse_gamelists->setState(Settings::getInstance()->getBool("ParseGamelistOnly"));
422 s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists);
423 s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); });
424
425 auto local_art = std::make_shared<SwitchComponent>(mWindow);
426 local_art->setState(Settings::getInstance()->getBool("LocalArt"));
427 s->addWithLabel("SEARCH FOR LOCAL ART", local_art);
428 s->addSaveFunc([local_art] { Settings::getInstance()->setBool("LocalArt", local_art->getState()); });
429
430 // hidden files
431 auto hidden_files = std::make_shared<SwitchComponent>(mWindow);
432 hidden_files->setState(Settings::getInstance()->getBool("ShowHiddenFiles"));
433 s->addWithLabel("SHOW HIDDEN FILES", hidden_files);
434 s->addSaveFunc([hidden_files] { Settings::getInstance()->setBool("ShowHiddenFiles", hidden_files->getState()); });
435
436 #ifdef _RPI_
437 // Video Player - VideoOmxPlayer
438 auto omx_player = std::make_shared<SwitchComponent>(mWindow);
439 omx_player->setState(Settings::getInstance()->getBool("VideoOmxPlayer"));
440 s->addWithLabel("USE OMX PLAYER (HW ACCELERATED)", omx_player);
441 s->addSaveFunc([omx_player]
442 {
443 // need to reload all views to re-create the right video components
444 bool needReload = false;
445 if(Settings::getInstance()->getBool("VideoOmxPlayer") != omx_player->getState())
446 needReload = true;
447
448 Settings::getInstance()->setBool("VideoOmxPlayer", omx_player->getState());
449
450 if(needReload)
451 ViewController::get()->reloadAll();
452 });
453
454 #endif
455
456 // framerate
457 auto framerate = std::make_shared<SwitchComponent>(mWindow);
458 framerate->setState(Settings::getInstance()->getBool("DrawFramerate"));
459 s->addWithLabel("SHOW FRAMERATE", framerate);
460 s->addSaveFunc([framerate] { Settings::getInstance()->setBool("DrawFramerate", framerate->getState()); });
461
462
463 mWindow->pushGui(s);
464
465 }
466
openConfigInput()467 void GuiMenu::openConfigInput()
468 {
469 Window* window = mWindow;
470 window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES",
471 [window] {
472 window->pushGui(new GuiDetectDevice(window, false, nullptr));
473 }, "NO", nullptr)
474 );
475
476 }
477
openQuitMenu()478 void GuiMenu::openQuitMenu()
479 {
480 auto s = new GuiSettings(mWindow, "QUIT");
481
482 Window* window = mWindow;
483
484 ComponentListRow row;
485 if (UIModeController::getInstance()->isUIModeFull())
486 {
487 row.makeAcceptInputHandler([window] {
488 window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
489 [] {
490 Scripting::fireEvent("quit");
491 if(quitES(QuitMode::RESTART) != 0)
492 LOG(LogWarning) << "Restart terminated with non-zero result!";
493 }, "NO", nullptr));
494 });
495 row.addElement(std::make_shared<TextComponent>(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
496 s->addRow(row);
497
498
499
500 if(Settings::getInstance()->getBool("ShowExit"))
501 {
502 row.elements.clear();
503 row.makeAcceptInputHandler([window] {
504 window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES",
505 [] {
506 Scripting::fireEvent("quit");
507 quitES();
508 }, "NO", nullptr));
509 });
510 row.addElement(std::make_shared<TextComponent>(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
511 s->addRow(row);
512 }
513 }
514 row.elements.clear();
515 row.makeAcceptInputHandler([window] {
516 window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES",
517 [] {
518 Scripting::fireEvent("quit", "reboot");
519 Scripting::fireEvent("reboot");
520 if (quitES(QuitMode::REBOOT) != 0)
521 LOG(LogWarning) << "Restart terminated with non-zero result!";
522 }, "NO", nullptr));
523 });
524 row.addElement(std::make_shared<TextComponent>(window, "RESTART SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
525 s->addRow(row);
526
527 row.elements.clear();
528 row.makeAcceptInputHandler([window] {
529 window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES",
530 [] {
531 Scripting::fireEvent("quit", "shutdown");
532 Scripting::fireEvent("shutdown");
533 if (quitES(QuitMode::SHUTDOWN) != 0)
534 LOG(LogWarning) << "Shutdown terminated with non-zero result!";
535 }, "NO", nullptr));
536 });
537 row.addElement(std::make_shared<TextComponent>(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
538 s->addRow(row);
539
540 mWindow->pushGui(s);
541 }
542
addVersionInfo()543 void GuiMenu::addVersionInfo()
544 {
545 std::string buildDate = (Settings::getInstance()->getBool("Debug") ? std::string( " (" + Utils::String::toUpper(PROGRAM_BUILT_STRING) + ")") : (""));
546
547 mVersion.setFont(Font::get(FONT_SIZE_SMALL));
548 mVersion.setColor(0x5E5E5EFF);
549 mVersion.setText("EMULATIONSTATION V" + Utils::String::toUpper(PROGRAM_VERSION_STRING) + buildDate);
550 mVersion.setHorizontalAlignment(ALIGN_CENTER);
551 addChild(&mVersion);
552 }
553
openScreensaverOptions()554 void GuiMenu::openScreensaverOptions() {
555 mWindow->pushGui(new GuiGeneralScreensaverOptions(mWindow, "SCREENSAVER SETTINGS"));
556 }
557
openCollectionSystemSettings()558 void GuiMenu::openCollectionSystemSettings() {
559 mWindow->pushGui(new GuiCollectionSystemsOptions(mWindow));
560 }
561
onSizeChanged()562 void GuiMenu::onSizeChanged()
563 {
564 mVersion.setSize(mSize.x(), 0);
565 mVersion.setPosition(0, mSize.y() - mVersion.getSize().y());
566 }
567
addEntry(const char * name,unsigned int color,bool add_arrow,const std::function<void ()> & func)568 void GuiMenu::addEntry(const char* name, unsigned int color, bool add_arrow, const std::function<void()>& func)
569 {
570 std::shared_ptr<Font> font = Font::get(FONT_SIZE_MEDIUM);
571
572 // populate the list
573 ComponentListRow row;
574 row.addElement(std::make_shared<TextComponent>(mWindow, name, font, color), true);
575
576 if(add_arrow)
577 {
578 std::shared_ptr<ImageComponent> bracket = makeArrow(mWindow);
579 row.addElement(bracket, false);
580 }
581
582 row.makeAcceptInputHandler(func);
583
584 mMenu.addRow(row);
585 }
586
input(InputConfig * config,Input input)587 bool GuiMenu::input(InputConfig* config, Input input)
588 {
589 if(GuiComponent::input(config, input))
590 return true;
591
592 if((config->isMappedTo("b", input) || config->isMappedTo("start", input)) && input.value != 0)
593 {
594 delete this;
595 return true;
596 }
597
598 return false;
599 }
600
getHelpStyle()601 HelpStyle GuiMenu::getHelpStyle()
602 {
603 HelpStyle style = HelpStyle();
604 style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
605 return style;
606 }
607
getHelpPrompts()608 std::vector<HelpPrompt> GuiMenu::getHelpPrompts()
609 {
610 std::vector<HelpPrompt> prompts;
611 prompts.push_back(HelpPrompt("up/down", "choose"));
612 prompts.push_back(HelpPrompt("a", "select"));
613 prompts.push_back(HelpPrompt("start", "close"));
614 return prompts;
615 }
616