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 #define DEBUG_MENU_ITEM 0
19 
20 #include "states_screens/main_menu_screen.hpp"
21 
22 #include "addons/news_manager.hpp"
23 #include "challenges/story_mode_timer.hpp"
24 #include "challenges/unlock_manager.hpp"
25 #include "config/player_manager.hpp"
26 #include "config/user_config.hpp"
27 #include "graphics/irr_driver.hpp"
28 #include "guiengine/dialog_queue.hpp"
29 #include "guiengine/scalable_font.hpp"
30 #include "guiengine/widgets/label_widget.hpp"
31 #include "guiengine/widgets/list_widget.hpp"
32 #include "guiengine/widgets/ribbon_widget.hpp"
33 #include "input/device_manager.hpp"
34 #include "input/input_manager.hpp"
35 #include "input/keyboard_device.hpp"
36 #include "io/file_manager.hpp"
37 #include "karts/kart_properties_manager.hpp"
38 #include "main_loop.hpp"
39 #include "modes/cutscene_world.hpp"
40 #include "modes/overworld.hpp"
41 #include "modes/demo_world.hpp"
42 #include "network/network_config.hpp"
43 #include "online/request_manager.hpp"
44 #include "states_screens/addons_screen.hpp"
45 #include "states_screens/credits.hpp"
46 #include "states_screens/cutscene_general.hpp"
47 #include "states_screens/grand_prix_editor_screen.hpp"
48 #include "states_screens/help_screen_1.hpp"
49 #include "states_screens/offline_kart_selection.hpp"
50 #include "states_screens/online/online_profile_achievements.hpp"
51 #include "states_screens/online/online_profile_servers.hpp"
52 #include "states_screens/online/online_screen.hpp"
53 #include "states_screens/options/options_screen_general.hpp"
54 #include "states_screens/state_manager.hpp"
55 #include "states_screens/options/user_screen.hpp"
56 #if DEBUG_MENU_ITEM
57 #include "states_screens/feature_unlocked.hpp"
58 #include "states_screens/grand_prix_lose.hpp"
59 #include "states_screens/grand_prix_win.hpp"
60 #endif
61 #include "states_screens/dialogs/message_dialog.hpp"
62 #include "tracks/track_manager.hpp"
63 #include "tracks/track.hpp"
64 #include "utils/string_utils.hpp"
65 #include "utils/translation.hpp"
66 
67 #include <string>
68 
69 
70 using namespace GUIEngine;
71 using namespace Online;
72 
73 // ----------------------------------------------------------------------------
74 
MainMenuScreen()75 MainMenuScreen::MainMenuScreen() : Screen("main_menu.stkgui")
76 {
77     m_resizable = true;
78 }   // MainMenuScreen
79 
80 // ----------------------------------------------------------------------------
81 
loadedFromFile()82 void MainMenuScreen::loadedFromFile()
83 {
84     LabelWidget* w = getWidget<LabelWidget>("info_addons");
85     w->setScrollSpeed(GUIEngine::getFontHeight() / 2);
86 
87     RibbonWidget* rw_top = getWidget<RibbonWidget>("menu_toprow");
88     assert(rw_top != NULL);
89 
90     if (track_manager->getTrack("overworld") == NULL ||
91         track_manager->getTrack("introcutscene") == NULL ||
92         track_manager->getTrack("introcutscene2") == NULL)
93     {
94         rw_top->removeChildNamed("story");
95     }
96 
97 #if DEBUG_MENU_ITEM != 1
98     RibbonWidget* rw = getWidget<RibbonWidget>("menu_bottomrow");
99     rw->removeChildNamed("test_gpwin");
100     rw->removeChildNamed("test_gplose");
101     rw->removeChildNamed("test_unlocked");
102     rw->removeChildNamed("test_unlocked2");
103     rw->removeChildNamed("test_intro");
104     rw->removeChildNamed("test_outro");
105 #endif
106 }   // loadedFromFile
107 
108 // ----------------------------------------------------------------------------
109 
beforeAddingWidget()110 void MainMenuScreen::beforeAddingWidget()
111 {
112 #ifdef IOS_STK
113     // iOS app doesn't like quit button in UI
114     Widget* w = getWidget("quit");
115     if (w)
116         w->setVisible(false);
117 #endif
118 }
119 
120 // ----------------------------------------------------------------------------
121 //
init()122 void MainMenuScreen::init()
123 {
124     GUIEngine::getDevice()->setResizable(true);
125     Screen::init();
126 
127     m_user_id = getWidget<ButtonWidget>("user-id");
128     assert(m_user_id);
129 
130     // reset in case we're coming back from a race
131     NetworkConfig::get()->cleanNetworkPlayers();
132     StateManager::get()->resetActivePlayers();
133     input_manager->getDeviceManager()->setAssignMode(NO_ASSIGN);
134     input_manager->getDeviceManager()->setSinglePlayer( NULL );
135     input_manager->setMasterPlayerOnly(false);
136 
137     // Avoid incorrect behaviour in certain race circumstances:
138     // If a multi-player game is played with two keyboards, the 2nd
139     // player selects his kart last, and only the keyboard is used
140     // to select all other settings - then if the next time the kart
141     // selection screen comes up, the default device will still be
142     // the 2nd player. So if the first player presses 'select', it
143     // will instead add a second player (so basically the key
144     // binding for the second player become the default, so pressing
145     // select will add a new player). See bug 3090931
146     // To avoid this, we will clean the last used device, making
147     // the key bindings for the first player the default again.
148     input_manager->getDeviceManager()->clearLatestUsedDevice();
149 
150 #ifndef SERVER_ONLY
151     if (addons_manager && addons_manager->isLoading())
152     {
153         IconButtonWidget* w = getWidget<IconButtonWidget>("addons");
154         w->setActive(false);
155         w->resetAllBadges();
156         w->setBadge(LOADING_BADGE);
157     }
158 
159     LabelWidget* w = getWidget<LabelWidget>("info_addons");
160     const core::stringw &news_text = NewsManager::get()->getNextNewsMessage();
161     w->setText(news_text, true);
162     w->update(0.01f);
163 #endif
164 
165     RibbonWidget* r = getWidget<RibbonWidget>("menu_bottomrow");
166     // FIXME: why do I need to do this manually
167     ((IconButtonWidget*)r->getChildren().get(0))->unfocused(PLAYER_ID_GAME_MASTER, NULL);
168     ((IconButtonWidget*)r->getChildren().get(1))->unfocused(PLAYER_ID_GAME_MASTER, NULL);
169     ((IconButtonWidget*)r->getChildren().get(2))->unfocused(PLAYER_ID_GAME_MASTER, NULL);
170 
171     r = getWidget<RibbonWidget>("menu_toprow");
172     r->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
173     DemoWorld::resetIdleTime();
174 
175 #ifdef IOS_STK
176     // iOS app doesn't like quit button in UI
177     Widget* quit = getWidget("quit");
178     if (quit)
179         quit->setVisible(false);
180 #endif
181 }   // init
182 
183 // ----------------------------------------------------------------------------
184 
onUpdate(float delta)185 void MainMenuScreen::onUpdate(float delta)
186 {
187 #ifndef SERVER_ONLY
188     NewsManager::get()->joinDownloadThreadIfExit();
189 
190     IconButtonWidget* addons_icon = getWidget<IconButtonWidget>("addons");
191     if (addons_icon != NULL)
192     {
193         if (addons_manager->wasError())
194         {
195             addons_icon->setActive(true);
196             addons_icon->resetAllBadges();
197             addons_icon->setBadge(BAD_BADGE);
198         }
199         else if (addons_manager->isLoading() && UserConfigParams::m_internet_status
200             == Online::RequestManager::IPERM_ALLOWED)
201         {
202             // Addons manager is still initialising/downloading.
203             addons_icon->setActive(false);
204             addons_icon->resetAllBadges();
205             addons_icon->setBadge(LOADING_BADGE);
206         }
207         else
208         {
209             addons_icon->setActive(true);
210             addons_icon->resetAllBadges();
211         }
212         // maybe add a new badge when not allowed to access the net
213     }
214 
215     LabelWidget* w = getWidget<LabelWidget>("info_addons");
216     w->update(delta);
217     if(w->scrolledOff())
218     {
219         const core::stringw &news_text = NewsManager::get()->getNextNewsMessage();
220         w->setText(news_text, true);
221     }
222 
223     PlayerProfile *player = PlayerManager::getCurrentPlayer();
224     if (!player)
225         return;
226     if(PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_GUEST  ||
227        PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN)
228     {
229         m_user_id->setText(player->getLastOnlineName() + "@stk");
230     }
231     else if (PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_OUT)
232     {
233         m_user_id->setText(player->getName());
234     }
235     else
236     {
237         // now must be either logging in or logging out
238         m_user_id->setText(player->getName());
239     }
240 
241     // Ask if user want to play tutorial when profile is newly created
242     if (player->getUseFrequency() != 0)
243         return;
244 
245     player->incrementUseFrequency();
246     class PlayTutorial :
247           public MessageDialog::IConfirmDialogListener
248     {
249     public:
250         virtual void onConfirm()
251         {
252             GUIEngine::ModalDialog::dismiss();
253             MainMenuScreen::getInstance()->startTutorial();
254         }   // onConfirm
255     };   // PlayTutorial
256 
257     MessageDialog* dialog =
258     new MessageDialog(_("Would you like to play the tutorial of the game?"),
259         MessageDialog::MESSAGE_DIALOG_YESNO, new PlayTutorial(),
260         true/*delete_listener*/, true/*from_queue*/);
261     GUIEngine::DialogQueue::get()->pushDialog(dialog,
262         false/*closes_any_dialog*/);
263 #endif
264 }   // onUpdate
265 
266 // ----------------------------------------------------------------------------
startTutorial()267 void MainMenuScreen::startTutorial()
268 {
269     RaceManager::get()->setNumPlayers(1);
270     RaceManager::get()->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
271     RaceManager::get()->setMinorMode (RaceManager::MINOR_MODE_TUTORIAL);
272     RaceManager::get()->setNumKarts( 1 );
273     RaceManager::get()->setTrack("tutorial");
274     RaceManager::get()->setDifficulty(RaceManager::DIFFICULTY_EASY);
275     RaceManager::get()->setReverseTrack(false);
276 
277     // Use keyboard 0 by default (FIXME: let player choose?)
278     InputDevice* device = input_manager->getDeviceManager()->getKeyboard(0);
279 
280     // Create player and associate player with keyboard
281     StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
282         device);
283 
284     if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
285     {
286         Log::warn("MainMenuScreen", "Cannot find kart '%s', will revert to default",
287             UserConfigParams::m_default_kart.c_str());
288         UserConfigParams::m_default_kart.revertToDefaults();
289     }
290     RaceManager::get()->setPlayerKart(0, UserConfigParams::m_default_kart);
291 
292     // ASSIGN should make sure that only input from assigned devices
293     // is read.
294     input_manager->getDeviceManager()->setAssignMode(ASSIGN);
295     input_manager->getDeviceManager()
296         ->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
297 
298     StateManager::get()->enterGameState();
299     RaceManager::get()->setupPlayerKartInfo();
300     RaceManager::get()->startNew(false);
301 }   // startTutorial
302 
303 // ----------------------------------------------------------------------------
304 
eventCallback(Widget * widget,const std::string & name,const int playerID)305 void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
306                                    const int playerID)
307 {
308 #ifndef SERVER_ONLY
309     if(name=="user-id")
310     {
311         UserScreen::getInstance()->push();
312         return;
313     }
314 
315     // most interesting stuff is in the ribbons, so start there
316     RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget);
317 
318     if (ribbon == NULL) return; // what's that event??
319 
320     // ---- A ribbon icon was clicked
321     std::string selection =
322         ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
323 
324     /*
325     if (selection == "story")
326     {
327         StateManager::get()->enterGameState();
328         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
329         RaceManager::get()->setNumKarts( 0 );
330         RaceManager::get()->setNumPlayers(0);
331         RaceManager::get()->setNumPlayers(0);
332         RaceManager::get()->startSingleRace("endcutscene", 999, false);
333 
334         std::vector<std::string> parts;
335         parts.push_back("introcutscene");
336         parts.push_back("introcutscene2");
337         ((CutsceneWorld*)World::getWorld())->setParts(parts);
338         //RaceManager::get()->startSingleRace("introcutscene2", 999, false);
339         return;
340     }
341     */
342 
343 #if DEBUG_MENU_ITEM
344     if (selection == "test_gpwin")
345     {
346         StoryModeStatus* sms = PlayerManager::getCurrentPlayer()->getStoryModeStatus();
347         sms->unlockFeature(const_cast<ChallengeStatus*>(sms->getChallengeStatus("gp1")),
348             RaceManager::DIFFICULTY_HARD);
349 
350         StateManager::get()->enterGameState();
351         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
352         RaceManager::get()->setNumKarts(0);
353         RaceManager::get()->setNumPlayers(0);
354         RaceManager::get()->setNumPlayers(0);
355         RaceManager::get()->startSingleRace("gpwin", 999, false);
356         GrandPrixWin* scene = GrandPrixWin::getInstance();
357         scene->push();
358         const std::pair<std::string, float> winners[] =
359             {
360                 { "kiki", 0.6f },
361                 { "nolok", 1.0f },
362                 { "pidgin", 0.0f },
363             };
364         scene->setKarts(winners);
365     }
366     else if (selection == "test_gplose")
367     {
368         StateManager::get()->enterGameState();
369         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
370         RaceManager::get()->setNumKarts(0);
371         RaceManager::get()->setNumPlayers(0);
372         RaceManager::get()->setNumPlayers(0);
373         RaceManager::get()->startSingleRace("gplose", 999, false);
374         GrandPrixLose* scene = GrandPrixLose::getInstance();
375         scene->push();
376         std::vector<std::pair<std::string, float> > losers;
377         losers.emplace_back("nolok", 1.0f);
378         losers.emplace_back("kiki", 0.6f);
379         //losers.push_back("wilber");
380         //losers.push_back("tux");
381         scene->setKarts(losers);
382     }
383     else if (selection == "test_unlocked" || selection == "test_unlocked2")
384     {
385         StoryModeStatus* sms = PlayerManager::getCurrentPlayer()->getStoryModeStatus();
386         sms->unlockFeature(const_cast<ChallengeStatus*>(sms->getChallengeStatus("gp1")),
387             RaceManager::DIFFICULTY_HARD);
388 
389         StateManager::get()->enterGameState();
390         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
391         RaceManager::get()->setNumKarts(0);
392         RaceManager::get()->setNumPlayers(0);
393         RaceManager::get()->setNumPlayers(0);
394         RaceManager::get()->startSingleRace("featunlocked", 999, false);
395 
396         FeatureUnlockedCutScene* scene =
397             FeatureUnlockedCutScene::getInstance();
398 
399         std::vector<std::string> parts;
400         parts.push_back("featunlocked");
401         ((CutsceneWorld*)World::getWorld())->setParts(parts);
402 
403         scene->addTrophy(RaceManager::DIFFICULTY_EASY, false);
404 
405         if (selection == "test_unlocked")
406         {
407             scene->addUnlockedKart(kart_properties_manager->getKart("tux"));
408             scene->addUnlockedTrack(track_manager->getTrack("lighthouse"));
409             scene->push();
410         }
411         else if (selection == "test_unlocked2")
412         {
413             std::vector<video::ITexture*> textures;
414             textures.push_back(irr_driver->getTexture(
415                 track_manager->getTrack("lighthouse")
416                              ->getScreenshotFile().c_str()));
417             textures.push_back(irr_driver->getTexture(
418                 track_manager->getTrack("snowtuxpeak")
419                              ->getScreenshotFile().c_str()));
420             textures.push_back(irr_driver->getTexture(
421                 track_manager->getTrack("sandtrack")
422                              ->getScreenshotFile().c_str()));
423             textures.push_back(irr_driver->getTexture(
424                 track_manager->getTrack("snowmountain")
425                              ->getScreenshotFile().c_str()));
426 
427             scene->addUnlockedPictures(textures, 4.0, 3.0, L"You unlocked <actual text would go here...>");
428 
429             scene->push();
430         }
431     }
432     else if (selection == "test_intro")
433     {
434         CutsceneWorld::setUseDuration(true);
435         StateManager::get()->enterGameState();
436         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
437         RaceManager::get()->setNumKarts(0);
438         RaceManager::get()->setNumPlayers(0);
439         RaceManager::get()->setNumPlayers(0);
440         RaceManager::get()->startSingleRace("introcutscene", 999, false);
441 
442         std::vector<std::string> parts;
443         parts.push_back("introcutscene");
444         parts.push_back("introcutscene2");
445         ((CutsceneWorld*)World::getWorld())->setParts(parts);
446         //RaceManager::get()->startSingleRace("introcutscene2", 999, false);
447 
448         CutSceneGeneral* scene = CutSceneGeneral::getInstance();
449         scene->push();
450         return;
451     }
452     else if (selection == "test_outro")
453     {
454         CutsceneWorld::setUseDuration(true);
455         StateManager::get()->enterGameState();
456         RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
457         RaceManager::get()->setNumKarts(0);
458         RaceManager::get()->setNumPlayers(0);
459         RaceManager::get()->setNumPlayers(0);
460         RaceManager::get()->startSingleRace("endcutscene", 999, false);
461 
462         std::vector<std::string> parts;
463         parts.push_back("endcutscene");
464         ((CutsceneWorld*)World::getWorld())->setParts(parts);
465 
466         CutSceneGeneral* scene = CutSceneGeneral::getInstance();
467         scene->push();
468     }
469     else
470 #endif
471     if (selection == "new")
472     {
473         NetworkConfig::get()->unsetNetworking();
474         KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance();
475         s->setMultiplayer(false);
476         s->setFromOverworld(false);
477         s->push();
478     }
479     else if (selection == "multiplayer")
480     {
481         KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance();
482         NetworkConfig::get()->unsetNetworking();
483         s->setMultiplayer(true);
484         s->setFromOverworld(false);
485         s->push();
486     }
487     else if (selection == "options")
488     {
489         OptionsScreenGeneral::getInstance()->push();
490     }
491     else if (selection == "quit")
492     {
493         StateManager::get()->popMenu();
494         return;
495     }
496     else if (selection == "about")
497     {
498         CreditsScreen::getInstance()->push();
499     }
500     else if (selection == "help")
501     {
502         HelpScreen1::getInstance()->push();
503     }
504     else if (selection == "startTutorial")
505     {
506         startTutorial();
507     }
508     else if (selection == "story")
509     {
510         NetworkConfig::get()->unsetNetworking();
511         PlayerProfile *player = PlayerManager::getCurrentPlayer();
512 
513         // Start the story mode (and speedrun) timer
514         story_mode_timer->startTimer();
515 
516         if (player->isFirstTime())
517         {
518             CutsceneWorld::setUseDuration(true);
519             StateManager::get()->enterGameState();
520             RaceManager::get()->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
521             RaceManager::get()->setNumKarts( 0 );
522             RaceManager::get()->setNumPlayers(0);
523             RaceManager::get()->startSingleRace("introcutscene", 999, false);
524 
525             std::vector<std::string> parts;
526             parts.push_back("introcutscene");
527             parts.push_back("introcutscene2");
528             ((CutsceneWorld*)World::getWorld())->setParts(parts);
529             //RaceManager::get()->startSingleRace("introcutscene2", 999, false);
530 
531             CutSceneGeneral* scene = CutSceneGeneral::getInstance();
532             scene->push();
533             return;
534         }
535         else
536         {
537             // Unpause the story mode timer when entering back the story mode
538             story_mode_timer->unpauseTimer(/* exit loading pause */ false);
539 
540             const std::string default_kart = UserConfigParams::m_default_kart;
541             if (player->isLocked(default_kart))
542             {
543                 KartSelectionScreen *next = OfflineKartSelectionScreen::getInstance();
544                 next->setGoToOverworldNext();
545                 next->setMultiplayer(false);
546                 next->push();
547                 return;
548             }
549             OverWorld::enterOverWorld();
550         }
551     }
552     else if (selection == "online")
553     {
554         if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED)
555         {
556             new MessageDialog(_("You can not play online without internet access. "
557                                 "If you want to play online, go in the options menu, "
558                                 "and check \"Connect to the Internet\"."));
559             return;
560         }
561         OnlineScreen::getInstance()->push();
562     }
563     else if (selection == "addons")
564     {
565         // Don't go to addons if there is no internet, unless some addons are
566         // already installed (so that you can delete addons without being online).
567         if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED)
568         {
569             if (!addons_manager->anyAddonsInstalled())
570             {
571                 new MessageDialog(_("You can not download addons without internet access. "
572                                     "If you want to download addons, go in the options menu, "
573                                     "and check \"Connect to the Internet\"."));
574                 return;
575             }
576             else
577             {
578                 AddonsScreen::getInstance()->push();
579                 new MessageDialog(_("You can not download addons without internet access. "
580                                     "If you want to download addons, go in the options menu, "
581                                     "and check \"Connect to the Internet\".\n\n"
582                                     "You can however delete already downloaded addons."));
583                 return;
584             }
585         }
586         AddonsScreen::getInstance()->push();
587     }
588     else if (selection == "gpEditor")
589     {
590         GrandPrixEditorScreen::getInstance()->push();
591     }
592     else if (selection == "achievements")
593     {
594         OnlineProfileAchievements::getInstance()->push();
595     }
596 #endif
597 }   // eventCallback
598 
599 // ----------------------------------------------------------------------------
600 
tearDown()601 void MainMenuScreen::tearDown()
602 {
603     GUIEngine::getDevice()->setResizable(false);
604 }   // tearDown
605 
606 // ----------------------------------------------------------------------------
607 
onDisabledItemClicked(const std::string & item)608 void MainMenuScreen::onDisabledItemClicked(const std::string& item)
609 {
610 #ifndef SERVER_ONLY
611     if (item == "addons")
612     {
613         if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED)
614         {
615             new MessageDialog( _("The add-ons module is currently disabled in "
616                                  "the Options screen") );
617         }
618         else if (addons_manager->wasError())
619         {
620             new MessageDialog( _("Sorry, an error occurred while contacting "
621                                  "the add-ons website. Make sure you are "
622                                  "connected to the Internet and that "
623                                  "SuperTuxKart is not blocked by a firewall"));
624         }
625         else if (addons_manager->isLoading())
626         {
627             new MessageDialog( _("Please wait while the add-ons are loading"));
628         }
629     }
630 #endif
631 }   // onDisabledItemClicked
632 
633 // ----------------------------------------------------------------------------
634 
onEscapePressed()635 bool MainMenuScreen::onEscapePressed()
636 {
637     return true;
638 }   // onEscapePressed
639