The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
title_screen.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
19 #include "game_config.hpp"
20 #include "game_preferences.hpp"
21 #include "gettext.hpp"
22 #include "log.hpp"
24 #include "gui/core/timer.hpp"
25 #include "gui/core/tips.hpp"
30 //#define DEBUG_TOOLTIP
31 #ifdef DEBUG_TOOLTIP
32 #include "gui/dialogs/tip.hpp"
33 #endif
34 #include "gui/widgets/button.hpp"
35 #include "gui/widgets/image.hpp"
36 #include "gui/widgets/label.hpp"
38 #include "gui/widgets/settings.hpp"
39 #include "gui/widgets/window.hpp"
40 #include "video.hpp"
41 
42 #include "utils/functional.hpp"
43 
44 #include <algorithm>
45 
46 static lg::log_domain log_config("config");
47 #define ERR_CF LOG_STREAM(err, log_config)
48 #define WRN_CF LOG_STREAM(warn, log_config)
49 
50 static lg::log_domain log_general("general");
51 #define ERR_GEN LOG_STREAM(err, log_general)
52 
53 namespace gui2
54 {
55 
56 /*WIKI
57  * @page = GUIWindowDefinitionWML
58  * @order = 2_title_screen
59  *
60  * == Title screen ==
61  *
62  * This shows the title screen.
63  *
64  * @begin{table}{dialog_widgets}
65  * tutorial & & button & m &
66  * The button to start the tutorial. $
67  *
68  * campaign & & button & m &
69  * The button to start a campaign. $
70  *
71  * multiplayer & & button & m &
72  * The button to start multiplayer mode. $
73  *
74  * load & & button & m &
75  * The button to load a saved game. $
76  *
77  * editor & & button & m &
78  * The button to start the editor. $
79  *
80  * addons & & button & m &
81  * The button to start managing the addons. $
82  *
83  * cores & & button & m &
84  * The button to start managing the cores. $
85  *
86  * language & & button & m &
87  * The button to select the game language. $
88  *
89  * credits & & button & m &
90  * The button to show Wesnoth's contributors. $
91  *
92  * quit & & button & m &
93  * The button to quit Wesnoth. $
94  *
95  * tips & & multi_page & m &
96  * A multi_page to hold all tips, when this widget is used the area of
97  * the tips doesn't need to be resized when the next or previous button
98  * is pressed. $
99  *
100  * -tip & & label & o &
101  * Shows the text of the current tip. $
102  *
103  * -source & & label & o &
104  * The source (the one who's quoted or the book referenced) of the
105  * current tip. $
106  *
107  * next_tip & & button & m &
108  * The button show the next tip of the day. $
109  *
110  * previous_tip & & button & m &
111  * The button show the previous tip of the day. $
112  *
113  * logo & & progress_bar & o &
114  * A progress bar to "animate" the Wesnoth logo. $
115  *
116  * revision_number & & control & o &
117  * A widget to show the version number when the version number is
118  * known. $
119  *
120  * @end{table}
121  */
122 
123 REGISTER_DIALOG(title_screen)
124 
126 
127 static bool hotkey(twindow& window, const ttitle_screen::tresult result)
128 {
129  window.set_retval(static_cast<twindow::tretval>(result));
130 
131  return true;
132 }
133 
134 ttitle_screen::ttitle_screen() : debug_clock_(nullptr)
135 {
136 }
137 
139 {
140  delete debug_clock_;
141 }
142 
143 static bool fullscreen(CVideo& video)
144 {
146 
147 
148  return true;
149 }
150 
151 static bool launch_lua_console(twindow & window)
152 {
154  return true;
155 }
156 
158 {
159  /** @todo Should become a title screen hotkey. */
160  window.register_hotkey(
162  std::bind(&hotkey, std::ref(window), RELOAD_GAME_DATA));
163 
165  std::bind(fullscreen, std::ref(window.video())));
166 
167  window.register_hotkey(
169  std::bind(&hotkey, std::ref(window), CHANGE_LANGUAGE));
170 
172  std::bind(&hotkey, std::ref(window), LOAD_GAME));
173 
175  std::bind(&hotkey, std::ref(window), SHOW_HELP));
176 
177  window.register_hotkey(
179  std::bind(&hotkey, std::ref(window), EDIT_PREFERENCES));
180 
181  std::function<void()> next_tip_wrapper = std::bind(
182  &ttitle_screen::update_tip, this, std::ref(window), true);
183 
184  window.register_hotkey(
186  std::bind(function_wrapper<bool, std::function<void()> >,
187  true,
188  next_tip_wrapper));
189 
190  std::function<void()> previous_tip_wrapper = std::bind(
191  &ttitle_screen::update_tip, this, std::ref(window), false);
192 
193  window.register_hotkey(
195  std::bind(function_wrapper<bool, std::function<void()> >,
196  true,
197  previous_tip_wrapper));
198 
200  std::bind(&hotkey, std::ref(window), TUTORIAL));
201 
202  window.register_hotkey(
204  std::bind(&hotkey, std::ref(window), NEW_CAMPAIGN));
205 
206  window.register_hotkey(
208  std::bind(&hotkey, std::ref(window), MULTIPLAYER));
209 
210  window.register_hotkey(
212  std::bind(&hotkey, std::ref(window), GET_ADDONS));
213 
215  std::bind(&hotkey, std::ref(window), CORES));
216 
217  window.register_hotkey(
219  std::bind(&hotkey, std::ref(window), START_MAP_EDITOR));
220 
221  window.register_hotkey(
223  std::bind(&hotkey, std::ref(window), SHOW_ABOUT));
224 
226  std::bind(&hotkey, std::ref(window), QUIT_GAME));
227 
228  window.register_hotkey(
230  std::bind(&launch_lua_console, std::ref(window)));
231 }
232 
233 #ifdef DEBUG_TOOLTIP
234 static void
235 debug_tooltip(twindow& window, bool& handled, const tpoint& coordinate)
236 {
237  std::string message = "Hello world.";
238  /*
239  * This function is used to test the tooltip placement algorithms as
240  * described in the »Tooltip placement« section in the GUI2 design
241  * document.
242  *
243  * Use a 1024 x 768 screen size, set the maximum loop iteration to:
244  * - 0 to test with a normal tooltip placement.
245  * - 30 to test with a larger normal tooltip placement.
246  * - 60 to test with a huge tooltip placement.
247  * - 150 to test with a borderline to insanely huge tooltip placement.
248  * - 180 to test with an insanely huge tooltip placement.
249  */
250  for(int i = 0; i < 0; ++i) {
251  message += " More greetings.";
252  }
254  gui2::tip::show(window.video(), "tooltip", message, coordinate);
255  handled = true;
256 }
257 #endif
258 
260 {
261  set_restore(false);
262  window.set_click_dismiss(false);
263  window.set_enter_disabled(true);
264  window.set_escape_disabled(true);
265 
266 #ifdef DEBUG_TOOLTIP
268  std::bind(debug_tooltip, std::ref(window), _3, _5),
270 #endif
271 
272  /**** Set the version number ****/
273  if(tcontrol* control
274  = find_widget<tcontrol>(&window, "revision_number", false, false)) {
275 
276  control->set_label(_("Version ") + game_config::revision);
277  }
278  window.canvas()[0].set_variable(
279  "revision_number",
280  variant(_("Version") + std::string(" ") + game_config::revision));
281 
282  /**** Set the tip of the day ****/
283  tmulti_page& tip_pages = find_widget<tmulti_page>(&window, "tips", false);
284 
285  std::vector<ttip> tips(settings::get_tips());
286  if(tips.empty()) {
287  WRN_CF << "There are not tips of day available." << std::endl;
288  }
289 
290  for(const auto & tip : tips)
291  {
292 
293  string_map widget;
294  std::map<std::string, string_map> page;
295 
296  widget["label"] = tip.text();
297  widget["use_markup"] = "true";
298  page["tip"] = widget;
299 
300  widget["label"] = tip.source();
301  widget["use_markup"] = "true";
302  page["source"] = widget;
303 
304  tip_pages.add_page(page);
305  }
306 
307  update_tip(window, true);
308 
310  find_widget<tbutton>(&window, "next_tip", false),
311  std::bind(&ttitle_screen::update_tip,
312  this,
313  std::ref(window),
314  true));
315 
317  find_widget<tbutton>(&window, "previous_tip", false),
318  std::bind(&ttitle_screen::update_tip,
319  this,
320  std::ref(window),
321  false));
322 
323  if(game_config::images::game_title.empty()) {
324  ERR_CF << "No title image defined" << std::endl;
325  } else {
326  window.canvas()[0].set_variable(
327  "title_image", variant(game_config::images::game_title));
328  }
329 
331  ERR_CF << "No title background image defined" << std::endl;
332  } else {
333  window.canvas()[0].set_variable(
334  "background_image",
336  }
337 
338  /***** Logo *****/
339  find_widget<timage>(&window, "logo", false).set_image("misc/logo.png");
340 
341  /***** About dialog button *****/
342  tbutton& about = find_widget<tbutton>(&window, "about", false);
344  about,
345  std::bind(&tgame_version::display, std::ref(window.video())));
346 
347  /***** Set the clock button. *****/
348  tbutton& clock = find_widget<tbutton>(&window, "clock", false);
351 
353  clock,
355  this,
356  std::ref(window.video())));
357 }
358 
359 void ttitle_screen::update_tip(twindow& window, const bool previous)
360 {
361  tmulti_page& tips = find_widget<tmulti_page>(&window, "tips", false);
362  if(tips.get_page_count() == 0) {
363  return;
364  }
365 
366  int page = tips.get_selected_page();
367  if(previous) {
368  if(page <= 0) {
369  page = tips.get_page_count();
370  }
371  --page;
372  } else {
373  ++page;
374  if(static_cast<unsigned>(page) >= tips.get_page_count()) {
375  page = 0;
376  }
377  }
378 
379  tips.select_page(page);
380  /**
381  * @todo Look for a proper fix.
382  *
383  * This dirtying is required to avoid the blurring to be rendered wrong.
384  * Not entirely sure why, but since we plan to move to SDL2 that change
385  * will probably fix this issue automatically.
386  */
387  window.set_is_dirty(true);
388 }
389 
391 {
392  assert(show_debug_clock_button);
393 
394  if(debug_clock_) {
395  delete debug_clock_;
396  debug_clock_ = nullptr;
397  } else {
398  debug_clock_ = new tdebug_clock();
399  debug_clock_->show(video, true);
400  }
401 }
402 
403 } // namespace gui2
Used to reload all game data.
static void display(CVideo &video, lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
Play single scenario against humans or AI.
CVideo & video()
Definition: window.hpp:411
void update_tip(twindow &window, const bool previous)
Updates the tip of day widget.
#define WRN_CF
Definition: video.hpp:58
std::string game_title
Definition: game_config.cpp:84
R function_wrapper(const R result, const F &function)
Helper for function wrappers.
Definition: helper.hpp:172
This file contains the window object, this object is a top level container which has the event manage...
const t_string & source() const
Definition: tips.hpp:62
REGISTER_DIALOG(label_settings)
void set_escape_disabled(const bool escape_disabled)
Disable the escape key.
Definition: window.hpp:358
void connect_signal_mouse_left_click(tdispatcher &dispatcher, const tsignal_function &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.hpp:710
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const thotkey_function &function)
Registers a hotkey.
Definition: dispatcher.cpp:303
Clock to test the draw events.
Definition: debug_clock.hpp:31
boost::enable_if< boost::mpl::has_key< tset_event, boost::mpl::int_< E > > >::type connect_signal(const tsignal_function &signal, const tposition position=back_child)
Connect a signal for callback in tset_event.
Definition: dispatcher.hpp:278
-file util.hpp
void pre_show(twindow &window)
Inherited from tdialog.
Start special campaign 'tutorial'.
Display credits about all contributors.
Keyboard shortcuts for game actions.
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
A SDL mouse motion event.
Definition: handler.hpp:64
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
Definition: window.hpp:345
Simple push button.
Definition: button.hpp:32
The user set the widget invisible, that means:
Definition: widget.hpp:103
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
GLuint64EXT * result
Definition: glew.h:10727
void show(CVideo &video, const bool allow_interaction=false, const unsigned auto_close_time=0)
Shows the window.
Definition: popup.cpp:34
static void display(CVideo &video)
The display function.
This file contains the settings handling of the widget library.
void remove()
Removes a tip.
Definition: tip.cpp:167
void set_restore(const bool restore)
Definition: dialog.hpp:171
bool fullscreen()
std::string game_title_background
Definition: game_config.cpp:84
const t_string & text() const
Definition: tips.hpp:58
int get_selected_page() const
Returns the selected page.
Definition: multi_page.cpp:90
void add_page(const string_map &item)
Adds single page to the grid.
Definition: multi_page.cpp:42
static lg::log_domain log_config("config")
The multi page class.
Definition: multi_page.hpp:37
This class implements the title screen.
std::map< std::string, t_string > string_map
Definition: generator.hpp:23
unsigned get_page_count() const
Returns the number of pages.
Definition: multi_page.cpp:78
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
Definition: tip.cpp:133
static ttip & tip()
Definition: tip.cpp:123
The user sets the widget visible, that means:
Definition: widget.hpp:79
static bool fullscreen(CVideo &video)
Definition: lobby.cpp:400
const std::string revision
Definition: game_config.cpp:57
size_t i
Definition: function.cpp:1057
Contains the gui2 timer routines.
Holds a 2D point.
Definition: point.hpp:24
void set_fullscreen(bool ison)
Definition: video.cpp:670
virtual void post_build(twindow &window)
Inherited from tdialog.
std::vector< tcanvas > & canvas()
Definition: control.hpp:282
void set_click_dismiss(const bool click_dismiss)
Definition: window.hpp:434
Base class for all visible items.
Definition: control.hpp:34
static lg::log_domain log_general("general")
void select_page(const unsigned page, const bool select=true)
Selectes a page.
Definition: multi_page.cpp:84
Let user select a campaign to play.
tpopup * debug_clock_
Holds the debug clock dialog.
GLenum GLint ref
Definition: glew.h:1813
bool show_debug_clock_button
Do we wish to show the button for the debug clock.
Standard logging facilities (interface).
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
void show_debug_clock_window(CVideo &video)
Shows the debug clock.
static bool launch_lua_console(twindow &window)
std::vector< ttip > get_tips()
Definition: settings.cpp:67
void set_visible(const tvisible::scoped_enum visible)
Definition: widget.cpp:445
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static std::vector< ttip > tips
Definition: settings.cpp:65
#define ERR_CF