The Battle for Wesnoth  1.15.7+dev
outro.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017-2018 by Charles Dang <exodia339@gmail.com>
3  Part of the Battle for Wesnoth Project https://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 
17 #include "gui/dialogs/outro.hpp"
18 
19 #include "about.hpp"
20 #include "formula/variant.hpp"
21 #include "game_classification.hpp"
22 #include "gettext.hpp"
24 #include "gui/core/timer.hpp"
25 #include "gui/widgets/settings.hpp"
26 #include "gui/widgets/window.hpp"
27 
28 #include <cmath>
29 
30 namespace gui2
31 {
32 namespace dialogs
33 {
34 REGISTER_DIALOG(outro)
35 
37  : text_()
38  , current_text_()
39  , duration_(info.end_text_duration)
40  , fade_step_(0)
41  , fading_in_(true)
42  , timer_id_(0)
43 {
44  if(!info.end_text.empty()) {
45  text_.push_back(info.end_text);
46  } else {
47  text_.push_back(_("The End"));
48  }
49 
50  text_.push_back("<span size='large'>" + info.campaign_name + "</span>");
51 
52  // We only show the end text and the title if credits were turned off
53  if(info.end_credits) {
54  const auto campaign_credits = about::get_campaign_credits(info.campaign);
55 
56  if(campaign_credits != about::get_credits_data().end()) {
57  for(const auto& about : campaign_credits->sections) {
58  if(about.names.empty()) {
59  continue;
60  }
61 
62  // Split the names into chunks of 5. Use float for proper ceil function!
63  static const float chunk_size = 5.0;
64 
65  const unsigned num_names = about.names.size();
66  const unsigned num_chunks = std::ceil(num_names / chunk_size);
67 
68  for(std::size_t i = 0; i < num_chunks; ++i) {
69  std::stringstream ss;
70 
71  // Only include section title on first chunk
72  if(i == 0) {
73  ss << about.title << "\n\n";
74  }
75 
76  for(std::size_t k = i * chunk_size; k < std::min<unsigned>((i + 1) * chunk_size, num_names); ++k) {
77  ss << "<span size='xx-small'>" << about.names[k].first << "</span>\n";
78  }
79 
80  // Clean up the trailing newline
81  std::string section_text = ss.str();
82  section_text.pop_back();
83 
84  text_.push_back(std::move(section_text));
85  }
86  }
87  }
88  }
89 
90  current_text_ = text_.begin();
91 
92  if(!duration_) {
93  duration_ = 3500; // 3.5 seconds
94  }
95 }
96 
98 {
99  window.set_enter_disabled(true);
100  window.get_canvas(0).set_variable("outro_text", wfl::variant(*current_text_));
101 
102  connect_signal_on_draw(window, std::bind(&outro::draw_callback, this));
103 }
104 
106 {
107  /* If we've faded fully in...
108  *
109  * NOTE: we want fading to take around half a second. Given this function runs about every 3 frames, we
110  * limit ourselves to a reasonable 10 fade steps with an alpha difference (rounded up) of 25.5 each cycle.
111  * The actual calculation for alpha is done in the window definition in WFL.
112  */
113  if(fading_in_ && fade_step_ > 10) {
114  // Schedule the fadeout after the provided delay.
115  if(timer_id_ == 0) {
116  timer_id_ = add_timer(duration_, [this](std::size_t) { fading_in_ = false; });
117  }
118 
119  return;
120  }
121 
122  canvas& window_canvas = get_window()->get_canvas(0);
123 
124  // If we've faded fully out...
125  if(!fading_in_ && fade_step_ < 0) {
126  std::advance(current_text_, 1);
127 
128  // ...and we've just showed the last text bit, close the window.
129  if(current_text_ == text_.end()) {
130  get_window()->close();
131  return;
132  }
133 
134  // ...else show the next bit.
135  window_canvas.set_variable("outro_text", wfl::variant(*current_text_));
136 
137  fading_in_ = true;
138  fade_step_ = 0;
139 
141  timer_id_ = 0;
142  }
143 
144  window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
145  window_canvas.set_is_dirty(true);
146 
147  get_window()->set_is_dirty(true);
148 
149  if(fading_in_) {
150  fade_step_++;
151  } else {
152  fade_step_--;
153  }
154 }
155 
156 void outro::post_show(window& /*window*/)
157 {
159  timer_id_ = 0;
160 }
161 
162 } // namespace dialogs
163 } // namespace gui2
void close()
Requests to close the window.
Definition: window.hpp:182
std::vector< std::string > text_
Definition: outro.hpp:54
credits_data::const_iterator get_campaign_credits(const std::string &campaign)
Gets credits for a given campaign.
Definition: about.cpp:99
logger & info()
Definition: log.cpp:91
const credits_data & get_credits_data()
Gets all credits data.
Definition: about.cpp:94
unsigned int duration_
Definition: outro.hpp:57
void set_variable(const std::string &key, const wfl::variant &value)
Definition: canvas.hpp:171
This file contains the window object, this object is a top level container which has the event manage...
window * get_window() const
Returns a pointer to the dialog&#39;s window.
Display credits about all contributors.
std::vector< std::string >::iterator current_text_
Definition: outro.hpp:55
std::size_t timer_id_
Definition: outro.hpp:62
Generic file dialog.
Definition: field-fwd.hpp:22
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:100
This file contains the settings handling of the widget library.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:465
Various uncategorised dialogs.
A simple canvas which can be drawn upon.
Definition: canvas.hpp:41
Dialog to display &#39;The End&#39; at the end of a campaign.
Definition: outro.hpp:26
void set_is_dirty(const bool is_dirty)
Definition: canvas.hpp:178
std::size_t i
Definition: function.cpp:933
Contains the gui2 timer routines.
std::size_t add_timer(const uint32_t interval, const std::function< void(std::size_t id)> &callback, const bool repeat)
Adds a new timer.
Definition: timer.cpp:126
void draw_callback()
Definition: outro.cpp:105
canvas & get_canvas(const unsigned index)
virtual void post_show(window &window) override
Inherited from modal_dialog.
Definition: outro.cpp:156
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
virtual void pre_show(window &window) override
Inherited from modal_dialog.
Definition: outro.cpp:97
void connect_signal_on_draw(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a callback when the widget is drawn.
Definition: dispatcher.cpp:191
auto * ss
Definition: result_set.cpp:281
bool remove_timer(const std::size_t id)
Removes a timer.
Definition: timer.cpp:167
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
Definition: window.hpp:286