1 // SuperTuxKart - a fun racing game with go-kart
2 // Copyright (C) 2009-2015 Marianne Gagnon
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 3
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 #include "states_screens/options/options_screen_ui.hpp"
19
20 #include "addons/news_manager.hpp"
21 #include "audio/sfx_manager.hpp"
22 #include "audio/sfx_base.hpp"
23 #include "graphics/camera.hpp"
24 #include "graphics/camera_normal.hpp"
25 #include "challenges/story_mode_timer.hpp"
26 #include "config/hardware_stats.hpp"
27 #include "config/player_manager.hpp"
28 #include "config/user_config.hpp"
29 #include "config/stk_config.hpp"
30 #include "font/bold_face.hpp"
31 #include "font/font_manager.hpp"
32 #include "font/regular_face.hpp"
33 #include "graphics/irr_driver.hpp"
34 #include "guiengine/scalable_font.hpp"
35 #include "guiengine/screen.hpp"
36 #include "guiengine/widgets/button_widget.hpp"
37 #include "guiengine/widgets/check_box_widget.hpp"
38 #include "guiengine/widgets/dynamic_ribbon_widget.hpp"
39 #include "guiengine/widgets/label_widget.hpp"
40 #include "guiengine/widgets/list_widget.hpp"
41 #include "guiengine/widgets/spinner_widget.hpp"
42 #include "guiengine/widget.hpp"
43 #include "io/file_manager.hpp"
44 #include "online/request_manager.hpp"
45 #include "states_screens/dialogs/message_dialog.hpp"
46 #include "states_screens/main_menu_screen.hpp"
47 #include "states_screens/dialogs/custom_camera_settings.hpp"
48 #include "states_screens/options/options_screen_audio.hpp"
49 #include "states_screens/options/options_screen_general.hpp"
50 #include "states_screens/options/options_screen_input.hpp"
51 #include "states_screens/options/options_screen_language.hpp"
52 #include "states_screens/options/options_screen_video.hpp"
53 #include "states_screens/state_manager.hpp"
54 #include "states_screens/options/user_screen.hpp"
55 #include "utils/log.hpp"
56 #include "utils/string_utils.hpp"
57 #include "utils/translation.hpp"
58
59 #include <algorithm>
60 #include <iostream>
61 #include <sstream>
62
63 using namespace GUIEngine;
64 using namespace Online;
65
66 // -----------------------------------------------------------------------------
67
OptionsScreenUI()68 OptionsScreenUI::OptionsScreenUI() : Screen("options_ui.stkgui")
69 {
70 m_inited = false;
71 } // OptionsScreenVideo
72
73 // -----------------------------------------------------------------------------
74
loadedFromFile()75 void OptionsScreenUI::loadedFromFile()
76 {
77 m_inited = false;
78
79 GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
80 assert( skinSelector != NULL );
81
82 skinSelector->m_properties[PROP_WRAP_AROUND] = "true";
83
84 // Setup the minimap options spinner
85 GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
86 assert( minimap_options != NULL );
87
88 minimap_options->m_properties[PROP_WRAP_AROUND] = "true";
89 minimap_options->clearLabels();
90 //I18N: In the UI options, minimap position in the race UI
91 minimap_options->addLabel( core::stringw(_("In the bottom-left")));
92 //I18N: In the UI options, minimap position in the race UI
93 minimap_options->addLabel( core::stringw(_("On the right side")));
94 //I18N: In the UI options, minimap position in the race UI
95 minimap_options->addLabel( core::stringw(_("Hidden")));
96 //I18N: In the UI options, minimap position in the race UI
97 minimap_options->addLabel( core::stringw(_("Centered")));
98 minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
99
100 bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
101 irr_driver->getDevice()->supportsTouchDevice()) ||
102 UserConfigParams::m_multitouch_active > 1;
103
104 if (multitouch_enabled && UserConfigParams::m_multitouch_draw_gui)
105 {
106 minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
107 }
108 minimap_options->m_properties[GUIEngine::PROP_MAX_VALUE] = "3";
109
110 // Setup splitscreen spinner
111 GUIEngine::SpinnerWidget* splitscreen_method = getWidget<GUIEngine::SpinnerWidget>("splitscreen_method");
112 splitscreen_method->m_properties[PROP_WRAP_AROUND] = "true";
113 splitscreen_method->clearLabels();
114 //I18N: In the UI options, splitscreen_method in the race UI
115 splitscreen_method->addLabel( core::stringw(_("Vertical")));
116 //I18N: In the UI options, splitscreen_method position in the race UI
117 splitscreen_method->addLabel( core::stringw(_("Horizontal")));
118 splitscreen_method->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
119 splitscreen_method->m_properties[GUIEngine::PROP_MAX_VALUE] = "1";
120
121 // Setup fontsize spinner
122 GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
123 assert( font_size != NULL );
124
125 font_size->clearLabels();
126 font_size->addLabel(L"Extremely small");
127 //I18N: In the UI options, Very small font size
128 font_size->addLabel(_("Very small"));
129 //I18N: In the UI options, Small font size
130 font_size->addLabel(_("Small"));
131 //I18N: In the UI options, Medium font size
132 font_size->addLabel(_("Medium"));
133 //I18N: In the UI options, Large font size
134 font_size->addLabel(_("Large"));
135 //I18N: In the UI options, Very large font size
136 font_size->addLabel(_("Very large"));
137 font_size->addLabel(L"Extremely large");
138
139 if (UserConfigParams::m_artist_debug_mode)
140 {
141 // Only show extreme size in artist debug mode
142 font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
143 font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "6";
144 }
145 else
146 {
147 font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
148 font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "5";
149 }
150
151 updateCameraPresetSpinner();
152
153 font_size->setValueUpdatedCallback([this](SpinnerWidget* spinner)
154 {
155 // Add a special value updated callback so font size is updated when
156 // it's pressed instead of release to prevent multiple event
157 bool right = spinner->isButtonSelected(true/*right*/);
158 UserConfigParams::m_font_size = spinner->getValue();
159 m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
160 m_reload_option->m_reload_font = true;
161 m_reload_option->m_reload_skin = false;
162 m_reload_option->m_focus_name = "font_size";
163 m_reload_option->m_focus_right = right;
164 });
165
166 } // loadedFromFile
167
168 // -----------------------------------------------------------------------------
169
init()170 void OptionsScreenUI::init()
171 {
172 Screen::init();
173 RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
174 assert(ribbon != NULL);
175 ribbon->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
176 ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER );
177
178 GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
179 assert( skinSelector != NULL );
180
181 m_skins.clear();
182 skinSelector->clearLabels();
183
184 std::set<std::string> skin_files;
185 file_manager->listFiles(skin_files /* out */, file_manager->getAsset(FileManager::SKIN,""),
186 true /* make full path */ );
187 std::set<std::string> addon_skin_files;
188 file_manager->listFiles(addon_skin_files /* out */, file_manager->getAddonsFile("skins/"),
189 true /* make full path */ );
190
191 auto lb = [](const std::set<std::string>& files, bool addon,
192 std::map<core::stringw, std::string>& result)->void
193 {
194 for (auto& f : files)
195 {
196 std::string stkskin = f + "/stkskin.xml";
197 if (file_manager->fileExists(stkskin))
198 {
199 XMLNode* root = file_manager->createXMLTree(stkskin);
200 if (!root)
201 continue;
202 core::stringw skin_name;
203 if (root->get("name", &skin_name))
204 {
205 std::string skin_id = StringUtils::getBasename(f);
206 if (addon)
207 skin_id = std::string("addon_") + skin_id;
208 result[skin_name] = skin_id;
209 }
210 delete root;
211 }
212 }
213 };
214 lb(skin_files, false, m_skins);
215 lb(addon_skin_files, true, m_skins);
216
217 if (m_skins.size() == 0)
218 {
219 Log::warn("OptionsScreenUI", "Could not find a single skin, make sure that "
220 "the data files are correctly installed");
221 skinSelector->setActive(false);
222 return;
223 }
224
225 const int skin_count = (int)m_skins.size();
226 for (auto& p : m_skins)
227 skinSelector->addLabel(p.first);
228 skinSelector->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
229 skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skin_count-1);
230
231 GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
232 assert( minimap_options != NULL );
233
234 bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
235 irr_driver->getDevice()->supportsTouchDevice()) ||
236 UserConfigParams::m_multitouch_active > 1;
237
238 if (multitouch_enabled && UserConfigParams::m_multitouch_draw_gui &&
239 UserConfigParams::m_minimap_display == 0)
240 {
241 UserConfigParams::m_minimap_display = 1;
242 }
243 minimap_options->setValue(UserConfigParams::m_minimap_display);
244
245 bool in_game = StateManager::get()->getGameState() == GUIEngine::INGAME_MENU;
246
247 GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
248 assert( font_size != NULL );
249
250 int size_int = (int)roundf(UserConfigParams::m_font_size);
251 if (size_int < 0 || size_int > 6)
252 size_int = 3;
253
254 if (!UserConfigParams::m_artist_debug_mode &&
255 (size_int < 1 || size_int > 5))
256 size_int = 3;
257
258 font_size->setValue(size_int);
259 UserConfigParams::m_font_size = font_size->getValue();
260 font_size->setActive(!in_game);
261
262 // ---- video modes
263 GUIEngine::SpinnerWidget* splitscreen_method = getWidget<GUIEngine::SpinnerWidget>("splitscreen_method");
264 assert( splitscreen_method != NULL );
265 if (UserConfigParams::split_screen_horizontally) splitscreen_method->setValue(1);
266 else splitscreen_method->setValue(0);
267 splitscreen_method->setActive(!in_game);
268
269 CheckBoxWidget* karts_powerup_gui = getWidget<CheckBoxWidget>("karts_powerup_gui");
270 assert(karts_powerup_gui != NULL);
271 karts_powerup_gui->setState(UserConfigParams::m_karts_powerup_gui);
272
273 CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");
274 assert( fps != NULL );
275 fps->setState( UserConfigParams::m_display_fps );
276
277 CheckBoxWidget* story_timer = getWidget<CheckBoxWidget>("story-mode-timer");
278 assert( story_timer != NULL );
279 story_timer->setState( UserConfigParams::m_display_story_mode_timer );
280 CheckBoxWidget* speedrun_timer = getWidget<CheckBoxWidget>("speedrun-timer");
281 assert( speedrun_timer != NULL );
282 if (story_mode_timer->getStoryModeTime() < 0)
283 {
284 story_timer->setActive(false);
285 speedrun_timer->setActive(false);
286 }
287 else
288 {
289 story_timer->setActive(true);
290
291 speedrun_timer->setActive(UserConfigParams::m_display_story_mode_timer);
292 getWidget<LabelWidget>("speedrun-timer-text")
293 ->setActive(UserConfigParams::m_display_story_mode_timer);
294 }
295 if (UserConfigParams::m_speedrun_mode)
296 {
297 if (!story_mode_timer->playerCanRun())
298 {
299 UserConfigParams::m_speedrun_mode = false;
300 new MessageDialog(_("Speedrun mode disabled. It can only be enabled if the game"
301 " has not been closed since the launch of the story mode.\n\n"
302 "Closing the game before the story mode's"
303 " completion invalidates the timer.\n\n"
304 "To use the speedrun mode, please use a new profile."),
305 MessageDialog::MESSAGE_DIALOG_OK,
306 NULL, false, false, 0.6f, 0.7f);
307 }
308 }
309 speedrun_timer->setState( UserConfigParams::m_speedrun_mode );
310
311 // --- select the right skin in the spinner
312 bool currSkinFound = false;
313 const std::string& user_skin = UserConfigParams::m_skin_file;
314 skinSelector->setActive(!in_game);
315
316 for (int n = 0; n <= skinSelector->getMax(); n++)
317 {
318 auto ret = m_skins.find(skinSelector->getStringValueFromID(n));
319 if (ret == m_skins.end())
320 continue;
321 const std::string skinFileName = ret->second;
322
323 if (user_skin == skinFileName)
324 {
325 skinSelector->setValue(n);
326 currSkinFound = true;
327 break;
328 }
329 }
330 if (!currSkinFound)
331 {
332 Log::warn("OptionsScreenUI",
333 "Couldn't find current skin in the list of skins!");
334 skinSelector->setValue(0);
335 irr_driver->unsetMaxTextureSize();
336 GUIEngine::reloadSkin();
337 irr_driver->setMaxTextureSize();
338 }
339
340 // Camera presets
341 m_camera_presets.push_back // Standard
342 ({
343 80 /* fov */, 1.0f /* distance */, 0.0f /* angle */, true /* smoothing */, 5.0f /* backward angle */,
344 });
345
346 m_camera_presets.push_back // Drone chase
347 ({
348 100 /* fov */, 2.6f /* distance */, 33.0f /* angle */, false /* smoothing */, 10.0f /* backward angle */,
349 });
350
351 GUIEngine::SpinnerWidget* camera_preset = getWidget<GUIEngine::SpinnerWidget>("camera_preset");
352 assert( camera_preset != NULL );
353
354 camera_preset->m_properties[PROP_WRAP_AROUND] = "true";
355 camera_preset->clearLabels();
356 //I18N: custom camera setting
357 camera_preset->addLabel( core::stringw(_("Custom")));
358 //I18N: In the UI options,litscreen_method in the race UI
359 camera_preset->addLabel( core::stringw(_("Standard")));
360 //I18N: In the UI options, splitscreen_method position in the race UI
361 camera_preset->addLabel( core::stringw(_("Drone chase")));
362 camera_preset->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
363 camera_preset->m_properties[GUIEngine::PROP_MAX_VALUE] = "2";
364
365 updateCameraPresetSpinner();
366 } // init
367
updateCamera()368 void OptionsScreenUI::updateCamera()
369 {
370 bool in_game = StateManager::get()->getGameState() == GUIEngine::INGAME_MENU;
371 if (in_game)
372 {
373 (Camera::getActiveCamera()->getCameraSceneNode())->setFOV(DEGREE_TO_RAD * UserConfigParams::m_camera_fov);
374 CameraNormal *camera = dynamic_cast<CameraNormal*>(Camera::getActiveCamera());
375 if (camera)
376 {
377 camera->setDistanceToKart(UserConfigParams::m_camera_distance);
378 }
379 }
380 }
381
updateCameraPresetSpinner()382 void OptionsScreenUI::updateCameraPresetSpinner()
383 {
384 GUIEngine::SpinnerWidget* camera_preset = getWidget<GUIEngine::SpinnerWidget>("camera_preset");
385 assert( camera_preset != NULL );
386
387 #define FLOAT_EPSILON 0.001
388
389 bool found = false;
390 unsigned int i = 0;
391 for (; i < m_camera_presets.size(); i++)
392 {
393 if (m_camera_presets[i].fov == UserConfigParams::m_camera_fov &&
394 m_camera_presets[i].smoothing == UserConfigParams::m_camera_forward_smoothing &&
395 fabs(m_camera_presets[i].distance - UserConfigParams::m_camera_distance) < FLOAT_EPSILON &&
396 fabs(m_camera_presets[i].angle - UserConfigParams::m_camera_forward_up_angle) < FLOAT_EPSILON &&
397 fabs(m_camera_presets[i].backward_angle - UserConfigParams::m_camera_backward_up_angle) < FLOAT_EPSILON)
398 {
399 camera_preset->setValue(i + 1);
400 found = true;
401 break;
402 }
403 }
404
405 if (!found)
406 {
407 camera_preset->setValue(0);
408 camera_preset->m_properties[GUIEngine::PROP_MIN_VALUE] = std::to_string(0);
409 }
410 updateCamera();
411
412 } // updateCameraPresetSpinner
413
414 // -----------------------------------------------------------------------------
415
eventCallback(Widget * widget,const std::string & name,const int playerID)416 void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, const int playerID)
417 {
418 #ifndef SERVER_ONLY
419 if (name == "options_choice")
420 {
421 std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
422
423 Screen *screen = NULL;
424 if (selection == "tab_audio")
425 screen = OptionsScreenAudio::getInstance();
426 else if (selection == "tab_video")
427 screen = OptionsScreenVideo::getInstance();
428 else if (selection == "tab_players")
429 screen = TabbedUserScreen::getInstance();
430 else if (selection == "tab_controls")
431 screen = OptionsScreenInput::getInstance();
432 //else if (selection == "tab_ui")
433 // screen = OptionsScreenUI::getInstance();
434 else if (selection == "tab_general")
435 screen = OptionsScreenGeneral::getInstance();
436 else if (selection == "tab_language")
437 screen = OptionsScreenLanguage::getInstance();
438 if(screen)
439 StateManager::get()->replaceTopMostScreen(screen);
440 }
441 else if(name == "back")
442 {
443 StateManager::get()->escapePressed();
444 }
445 else if (name == "skinchoice")
446 {
447 GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
448 assert( skinSelector != NULL );
449
450 const core::stringw selectedSkin = skinSelector->getStringValue();
451 bool right = skinSelector->isButtonSelected(true/*right*/);
452 UserConfigParams::m_skin_file = m_skins[selectedSkin];
453 bool prev_font = GUIEngine::getSkin()->hasFont();
454 irr_driver->unsetMaxTextureSize();
455 GUIEngine::reloadSkin();
456 // Reload GUIEngine will clear widgets so we don't do that in eventCallback
457 m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
458 m_reload_option->m_reload_font = prev_font != GUIEngine::getSkin()->hasFont();
459 m_reload_option->m_reload_skin = true;
460 m_reload_option->m_focus_name = "skinchoice";
461 m_reload_option->m_focus_right = right;
462 }
463 else if (name == "minimap")
464 {
465 GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
466 assert( minimap_options != NULL );
467 UserConfigParams::m_minimap_display = minimap_options->getValue();
468 }
469 else if (name == "font_size")
470 {
471 GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
472 assert( font_size != NULL );
473 bool right = font_size->isButtonSelected(true/*right*/);
474 UserConfigParams::m_font_size = font_size->getValue();
475 // Reload GUIEngine will clear widgets so we don't do that in eventCallback
476 m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
477 m_reload_option->m_reload_font = true;
478 m_reload_option->m_reload_skin = false;
479 m_reload_option->m_focus_name = "font_size";
480 m_reload_option->m_focus_right = right;
481 }
482 else if (name == "splitscreen_method")
483 {
484 GUIEngine::SpinnerWidget* splitscreen_method = getWidget<GUIEngine::SpinnerWidget>("splitscreen_method");
485 assert( splitscreen_method != NULL );
486 UserConfigParams::split_screen_horizontally = (splitscreen_method->getValue() == 1);
487 }
488 else if (name == "karts_powerup_gui")
489 {
490 CheckBoxWidget* karts_powerup_gui = getWidget<CheckBoxWidget>("karts_powerup_gui");
491 assert(karts_powerup_gui != NULL);
492 UserConfigParams::m_karts_powerup_gui = karts_powerup_gui->getState();
493 }
494 else if (name == "showfps")
495 {
496 CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");
497 assert( fps != NULL );
498 UserConfigParams::m_display_fps = fps->getState();
499 }
500 else if (name == "story-mode-timer")
501 {
502 CheckBoxWidget* story_timer = getWidget<CheckBoxWidget>("story-mode-timer");
503 assert( story_timer != NULL );
504 UserConfigParams::m_display_story_mode_timer = story_timer->getState();
505
506 CheckBoxWidget* speedrun_timer = getWidget<CheckBoxWidget>("speedrun-timer");
507 assert( speedrun_timer != NULL );
508 speedrun_timer->setActive( UserConfigParams::m_display_story_mode_timer );
509 getWidget<LabelWidget>("speedrun-timer-text")
510 ->setActive(UserConfigParams::m_display_story_mode_timer);
511
512 // Disable speedrun mode if the story mode timer is disabled
513 if (!UserConfigParams::m_display_story_mode_timer)
514 {
515 UserConfigParams::m_speedrun_mode = false;
516 speedrun_timer->setState(false);
517 }
518
519 }
520 else if (name == "speedrun-timer")
521 {
522 CheckBoxWidget* speedrun_timer = getWidget<CheckBoxWidget>("speedrun-timer");
523 assert( speedrun_timer != NULL );
524 if (speedrun_timer->getState())
525 {
526 if (!story_mode_timer->playerCanRun())
527 {
528 speedrun_timer->setState(false);
529 new MessageDialog(_("Speedrun mode can only be enabled if the game has not"
530 " been closed since the launch of the story mode.\n\n"
531 "Closing the game before the story mode's"
532 " completion invalidates the timer.\n\n"
533 "To use the speedrun mode, please use a new profile."),
534 MessageDialog::MESSAGE_DIALOG_OK,
535 NULL, false, false, 0.6f, 0.7f);
536 }
537 }
538 UserConfigParams::m_speedrun_mode = speedrun_timer->getState();
539 }
540 else if (name == "camera_preset")
541 {
542 GUIEngine::SpinnerWidget* camera_preset = getWidget<GUIEngine::SpinnerWidget>("camera_preset");
543 assert( camera_preset != NULL );
544 unsigned int i = camera_preset->getValue();
545 if (i != 0) {
546 UserConfigParams::m_camera_fov = m_camera_presets[i-1].fov;
547 UserConfigParams::m_camera_distance = m_camera_presets[i-1].distance;
548 UserConfigParams::m_camera_forward_up_angle = m_camera_presets[i-1].angle;
549 UserConfigParams::m_camera_forward_smoothing = m_camera_presets[i-1].smoothing;
550 UserConfigParams::m_camera_backward_up_angle = m_camera_presets[i-1].backward_angle;
551 }
552 updateCamera();
553 }
554 else if(name == "custom_camera")
555 {
556 new CustomCameraSettingsDialog(0.8f, 0.9f);
557 }
558 #endif
559 } // eventCallback
560
561 // -----------------------------------------------------------------------------
562
onUpdate(float delta)563 void OptionsScreenUI::onUpdate(float delta)
564 {
565 if (m_reload_option)
566 reloadGUIEngine();
567 } // onUpdate
568
569 // -----------------------------------------------------------------------------
570
reloadGUIEngine()571 void OptionsScreenUI::reloadGUIEngine()
572 {
573 bool reload_font = m_reload_option->m_reload_font;
574 bool reload_skin = m_reload_option->m_reload_skin;
575 std::string focus_name = m_reload_option->m_focus_name;
576 bool focus_right = m_reload_option->m_focus_right;
577
578 if (reload_skin || reload_font)
579 {
580 if (reload_font)
581 {
582 GUIEngine::clear();
583 GUIEngine::cleanUp();
584 }
585
586 GUIEngine::clearScreenCache();
587
588 if (reload_font)
589 {
590 delete font_manager;
591 font_manager = new FontManager();
592 font_manager->loadFonts();
593 GUIEngine::init(irr_driver->getDevice(), irr_driver->getVideoDriver(),
594 StateManager::get(), false/*loading*/);
595 }
596
597 Screen* screen_list[] =
598 {
599 MainMenuScreen::getInstance(),
600 OptionsScreenUI::getInstance(),
601 nullptr
602 };
603 GUIEngine::switchToScreen(MainMenuScreen::getInstance());
604 StateManager::get()->resetAndSetStack(screen_list);
605 GUIEngine::SpinnerWidget* spinner = OptionsScreenUI::getInstance()
606 ->getWidget<GUIEngine::SpinnerWidget>(focus_name.c_str());
607 spinner->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
608 spinner->setSelectedButton(focus_right);
609 }
610 if (reload_skin)
611 {
612 irr_driver->setMaxTextureSize();
613 }
614 OptionsScreenUI::getInstance()->m_reload_option = nullptr;
615 } // reloadGUIEngine
616
617 // -----------------------------------------------------------------------------
618
tearDown()619 void OptionsScreenUI::tearDown()
620 {
621 Screen::tearDown();
622 // save changes when leaving screen
623 user_config->saveConfig();
624 } // tearDown
625
626 // -----------------------------------------------------------------------------
627
unloaded()628 void OptionsScreenUI::unloaded()
629 {
630 m_inited = false;
631 } // unloaded
632
633 // -----------------------------------------------------------------------------
634