gui/dialogs/title_screen.cpp

Go to the documentation of this file.
00001 /* $Id: title_screen.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017 
00018 #include "gui/dialogs/title_screen.hpp"
00019 
00020 #include "display.hpp"
00021 #include "game_config.hpp"
00022 #include "game_preferences.hpp"
00023 #include "gettext.hpp"
00024 #include "log.hpp"
00025 #include "gui/auxiliary/timer.hpp"
00026 #include "gui/auxiliary/tips.hpp"
00027 #include "gui/dialogs/debug_clock.hpp"
00028 #include "gui/dialogs/language_selection.hpp"
00029 #include "gui/widgets/button.hpp"
00030 #include "gui/widgets/label.hpp"
00031 #include "gui/widgets/multi_page.hpp"
00032 #include "gui/widgets/progress_bar.hpp"
00033 #include "gui/widgets/settings.hpp"
00034 #include "gui/widgets/window.hpp"
00035 #include "preferences_display.hpp"
00036 
00037 #include <boost/bind.hpp>
00038 
00039 #include <algorithm>
00040 
00041 static lg::log_domain log_config("config");
00042 #define ERR_CF LOG_STREAM(err, log_config)
00043 #define WRN_CF LOG_STREAM(warn, log_config)
00044 
00045 namespace gui2 {
00046 
00047 /*WIKI
00048  * @page = GUIWindowDefinitionWML
00049  * @order = 2_title_screen
00050  *
00051  * == Title screen ==
00052  *
00053  * This shows the title screen.
00054  *
00055  * @begin{table}{dialog_widgets}
00056  * tutorial & & button & m &
00057  *         The button to start the tutorial. $
00058  *
00059  * campaign & & button & m &
00060  *         The button to start a campaign. $
00061  *
00062  * multiplayer & & button & m &
00063  *         The button to start multiplayer mode. $
00064  *
00065  * load & & button & m &
00066  *         The button to load a saved game. $
00067  *
00068  * editor & & button & m &
00069  *         The button to start the editor. $
00070  *
00071  * addons & & button & m &
00072  *         The button to start managing the addons. $
00073  *
00074  * language & & button & m &
00075  *         The button to select the game language. $
00076  *
00077  * credits & & button & m &
00078  *         The button to show Wesnoth's contributors. $
00079  *
00080  * quit & & button & m &
00081  *         The button to quit Wesnoth. $
00082  *
00083  * tips & & multi_page & m &
00084  *         A multi_page to hold all tips, when this widget is used the area of
00085  *         the tips doesn't need to be resized when the next or previous button
00086  *         is pressed. $
00087  *
00088  * -tip & & label & o &
00089  *         Shows the text of the current tip. $
00090  *
00091  * -source & & label & o &
00092  *         The source (the one who's quoted or the book referenced) of the
00093  *         current tip. $
00094  *
00095  * next_tip & & button & m &
00096  *         The button show the next tip of the day. $
00097  *
00098  * previous_tip & & button & m &
00099  *         The button show the previous tip of the day. $
00100  *
00101  * logo & & progress_bar & o &
00102  *         A progress bar to "animate" the Wesnoth logo. $
00103  *
00104  * revision_number & & control & o &
00105  *         A widget to show the version number when the version number is
00106  *         known. $
00107  *
00108  * @end{table}
00109  */
00110 
00111 REGISTER_DIALOG(title_screen)
00112 
00113 bool show_debug_clock_button = false;
00114 
00115 static bool hotkey(twindow& window, const ttitle_screen::tresult result)
00116 {
00117     window.set_retval(static_cast<twindow::tretval>(result));
00118 
00119     return true;
00120 }
00121 
00122 ttitle_screen::ttitle_screen()
00123     : logo_timer_id_(0)
00124     , debug_clock_(NULL)
00125 {
00126 }
00127 
00128 ttitle_screen::~ttitle_screen()
00129 {
00130     if(logo_timer_id_) {
00131         remove_timer(logo_timer_id_);
00132     }
00133     delete debug_clock_;
00134 }
00135 
00136 static void animate_logo(
00137           unsigned long& timer_id
00138         , unsigned& percentage
00139         , tprogress_bar& progress_bar
00140         , twindow& window)
00141 {
00142     assert(percentage <= 100);
00143     ++percentage;
00144     progress_bar.set_percentage(percentage);
00145 
00146     /*
00147      * The progress bar may overlap (actually underlap) other widgets, which
00148      * the update invalidates, so make sure the whole window is redrawn to fix
00149      * this possible problem. Of course this is expensive but the logo is
00150      * animated once so the cost is only once.
00151      */
00152     window.set_dirty();
00153 
00154     if(percentage == 100) {
00155         remove_timer(timer_id);
00156         timer_id = 0;
00157     }
00158 }
00159 
00160 static bool fullscreen(CVideo& video)
00161 {
00162     preferences::set_fullscreen(video , !preferences::fullscreen());
00163 
00164     // Setting to fullscreen doesn't seem to generate a resize event.
00165     const SDL_Rect& rect = screen_area();
00166 
00167     SDL_Event event;
00168     event.type = SDL_VIDEORESIZE;
00169     event.resize.type = SDL_VIDEORESIZE;
00170     event.resize.w = rect.w;
00171     event.resize.h = rect.h;
00172 
00173     SDL_PushEvent(&event);
00174 
00175     return true;
00176 }
00177 
00178 void ttitle_screen::post_build(CVideo& video, twindow& window)
00179 {
00180     /** @todo Should become a title screen hotkey. */
00181     window.register_hotkey(hotkey::TITLE_SCREEN__RELOAD_WML
00182                 , boost::bind(
00183                       &hotkey
00184                     , boost::ref(window)
00185                     , RELOAD_GAME_DATA));
00186 
00187     window.register_hotkey(hotkey::HOTKEY_FULLSCREEN
00188             , boost::bind(fullscreen, boost::ref(video)));
00189 
00190     window.register_hotkey(hotkey::HOTKEY_LANGUAGE
00191                 , boost::bind(
00192                       &hotkey
00193                     , boost::ref(window)
00194                     , CHANGE_LANGUAGE));
00195 
00196     window.register_hotkey(hotkey::HOTKEY_LOAD_GAME
00197                 , boost::bind(
00198                       &hotkey
00199                     , boost::ref(window)
00200                     , LOAD_GAME));
00201 
00202     window.register_hotkey(hotkey::HOTKEY_HELP
00203                 , boost::bind(
00204                       &hotkey
00205                     , boost::ref(window)
00206                     , SHOW_HELP));
00207 
00208     window.register_hotkey(hotkey::HOTKEY_PREFERENCES
00209                 , boost::bind(
00210                       &hotkey
00211                     , boost::ref(window)
00212                     , EDIT_PREFERENCES));
00213 
00214     static const boost::function<void()> next_tip_wrapper = boost::bind(
00215               &ttitle_screen::update_tip
00216             , this
00217             , boost::ref(window)
00218             , true);
00219 
00220     window.register_hotkey(hotkey::TITLE_SCREEN__NEXT_TIP
00221             , boost::bind(function_wrapper<bool, boost::function<void()> >
00222                 , true
00223                 , boost::cref(next_tip_wrapper)));
00224 
00225     static const boost::function<void()> previous_tip_wrapper = boost::bind(
00226               &ttitle_screen::update_tip
00227             , this
00228             , boost::ref(window)
00229             , false);
00230 
00231     window.register_hotkey(hotkey::TITLE_SCREEN__PREVIOUS_TIP
00232             , boost::bind(function_wrapper<bool, boost::function<void()> >
00233                 , true
00234                 , boost::cref(previous_tip_wrapper)));
00235 
00236     window.register_hotkey(hotkey::TITLE_SCREEN__TUTORIAL
00237                 , boost::bind(
00238                       &hotkey
00239                     , boost::ref(window)
00240                     , TUTORIAL));
00241 
00242     window.register_hotkey(hotkey::TITLE_SCREEN__TUTORIAL
00243                 , boost::bind(
00244                       &hotkey
00245                     , boost::ref(window)
00246                     , TUTORIAL));
00247 
00248     window.register_hotkey(hotkey::TITLE_SCREEN__CAMPAIGN
00249                 , boost::bind(
00250                       &hotkey
00251                     , boost::ref(window)
00252                     , NEW_CAMPAIGN));
00253 
00254     window.register_hotkey(hotkey::TITLE_SCREEN__MULTIPLAYER
00255                 , boost::bind(
00256                       &hotkey
00257                     , boost::ref(window)
00258                     , MULTIPLAYER));
00259 
00260     window.register_hotkey(hotkey::TITLE_SCREEN__ADDONS
00261                 , boost::bind(
00262                       &hotkey
00263                     , boost::ref(window)
00264                     , GET_ADDONS));
00265 
00266     window.register_hotkey(hotkey::TITLE_SCREEN__EDITOR
00267                 , boost::bind(
00268                       &hotkey
00269                     , boost::ref(window)
00270                     , START_MAP_EDITOR));
00271 
00272     window.register_hotkey(hotkey::TITLE_SCREEN__CREDITS
00273                 , boost::bind(
00274                       &hotkey
00275                     , boost::ref(window)
00276                     , SHOW_ABOUT));
00277 
00278     window.register_hotkey(hotkey::HOTKEY_QUIT_GAME
00279                 , boost::bind(
00280                       &hotkey
00281                     , boost::ref(window)
00282                     , QUIT_GAME));
00283 }
00284 
00285 void ttitle_screen::pre_show(CVideo& video, twindow& window)
00286 {
00287     set_restore(false);
00288     window.set_click_dismiss(false);
00289     window.set_enter_disabled(true);
00290     window.set_escape_disabled(true);
00291 
00292     /**** Set the version number ****/
00293     if(tcontrol* control
00294             = find_widget<tcontrol>(&window, "revision_number", false, false)) {
00295 
00296         control->set_label(_("Version ") + game_config::revision);
00297     }
00298     window.canvas()[0].set_variable("revision_number",
00299         variant(_("Version") + std::string(" ") + game_config::revision));
00300 
00301     /**** Set the tip of the day ****/
00302     tmulti_page& tip_pages = find_widget<tmulti_page>(&window, "tips", false);
00303 
00304     std::vector<ttip> tips(settings::get_tips());
00305     if(tips.empty()) {
00306         WRN_CF << "There are not tips of day available.\n";
00307     }
00308 
00309     foreach(const ttip& tip, tips) {
00310 
00311         string_map widget;
00312         std::map<std::string, string_map> page;
00313 
00314         widget["label"] = tip.text();
00315         widget["use_markup"] = "true";
00316         page["tip"] = widget;
00317 
00318         widget["label"] = tip.source();
00319         widget["use_markup"] = "true";
00320         page["source"] = widget;
00321 
00322         tip_pages.add_page(page);
00323     }
00324 
00325     update_tip(window, true);
00326 
00327     connect_signal_mouse_left_click(
00328               find_widget<tbutton>(&window, "next_tip", false)
00329             , boost::bind(
00330                   &ttitle_screen::update_tip
00331                 , this
00332                 , boost::ref(window)
00333                 , true));
00334 
00335     connect_signal_mouse_left_click(
00336               find_widget<tbutton>(&window, "previous_tip", false)
00337             , boost::bind(
00338                   &ttitle_screen::update_tip
00339                 , this
00340                 , boost::ref(window)
00341                 , false));
00342 
00343     if(game_config::images::game_title.empty()) {
00344         ERR_CF << "No title image defined\n";
00345     } else {
00346         window.canvas()[0].set_variable("background_image",
00347             variant(game_config::images::game_title));
00348     }
00349 
00350     /***** Set the logo *****/
00351     tprogress_bar* logo =
00352             find_widget<tprogress_bar>(&window, "logo", false, false);
00353     if(logo) {
00354         /*
00355          * A 'singleton' value, since the progress bar only needs to progress
00356          * once its state needs to be global.
00357          */
00358         static unsigned percentage = preferences::startup_effect() ? 0 : 100;
00359         logo->set_percentage(percentage);
00360 
00361         if(percentage < 100) {
00362             /*
00363              * The interval is empirically determined  so that the speed "felt"
00364              * good.
00365              */
00366             logo_timer_id_ = add_timer(30
00367                     , boost::bind(animate_logo
00368                         , boost::ref(logo_timer_id_)
00369                         , boost::ref(percentage)
00370                         , boost::ref(*logo)
00371                         , boost::ref(window))
00372                     , true);
00373         }
00374     }
00375 
00376     /***** Set the clock button. *****/
00377     tbutton& clock = find_widget<tbutton>(&window, "clock", false);
00378     clock.set_visible(show_debug_clock_button
00379             ? twidget::VISIBLE
00380             : twidget::INVISIBLE);
00381 
00382     connect_signal_mouse_left_click(
00383               clock
00384             , boost::bind(
00385                   &ttitle_screen::show_debug_clock_window
00386                 , this
00387                 , boost::ref(video)));
00388 }
00389 
00390 void ttitle_screen::update_tip(twindow& window, const bool previous)
00391 {
00392     tmulti_page& tips = find_widget<tmulti_page>(&window, "tips", false);
00393     if(tips.get_page_count() == 0) {
00394         return;
00395     }
00396 
00397     int page = tips.get_selected_page();
00398     if(previous) {
00399         if(page <= 0) {
00400             page = tips.get_page_count();
00401         }
00402         --page;
00403     } else {
00404         ++page;
00405         if(static_cast<unsigned>(page) >= tips.get_page_count()) {
00406             page = 0;
00407         }
00408     }
00409 
00410     tips.select_page(page);
00411 }
00412 
00413 void ttitle_screen::show_debug_clock_window(CVideo& video)
00414 {
00415     assert(show_debug_clock_button);
00416 
00417     if(debug_clock_) {
00418         delete debug_clock_;
00419         debug_clock_ = NULL;
00420     } else {
00421         debug_clock_ = new tdebug_clock();
00422         debug_clock_->show(video, true);
00423     }
00424 }
00425 
00426 } // namespace gui2
00427 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:58 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs