The Battle for Wesnoth  1.15.12+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::dialogs
31 {
32 REGISTER_DIALOG(outro)
33 
35  : text_()
36  , current_text_()
37  , duration_(info.end_text_duration)
38  , fade_step_(0)
39  , fading_in_(true)
40  , timer_id_(0)
41 {
42  if(!info.end_text.empty()) {
43  text_.push_back(info.end_text);
44  } else {
45  text_.push_back(_("The End"));
46  }
47 
48  if(info.end_credits) {
49  text_.push_back("<span size='large'>" + info.campaign_name + "</span>");
50 
51  const auto campaign_credits = about::get_campaign_credits(info.campaign);
52 
53  if(campaign_credits != about::get_credits_data().end()) {
54  for(const auto& about : campaign_credits->sections) {
55  if(about.names.empty()) {
56  continue;
57  }
58 
59  // Split the names into chunks of 5. Use float for proper ceil function!
60  static const float chunk_size = 5.0;
61 
62  const unsigned num_names = about.names.size();
63  const unsigned num_chunks = std::ceil(num_names / chunk_size);
64 
65  for(std::size_t i = 0; i < num_chunks; ++i) {
66  std::stringstream ss;
67 
68  // Only include section title on first chunk
69  if(i == 0) {
70  ss << about.title << "\n\n";
71  }
72 
73  for(std::size_t k = i * chunk_size; k < std::min<unsigned>((i + 1) * chunk_size, num_names); ++k) {
74  ss << "<span size='xx-small'>" << about.names[k].first << "</span>\n";
75  }
76 
77  // Clean up the trailing newline
78  std::string section_text = ss.str();
79  section_text.pop_back();
80 
81  text_.push_back(std::move(section_text));
82  }
83  }
84  }
85  }
86 
87  current_text_ = text_.begin();
88 
89  if(!duration_) {
90  duration_ = 3500; // 3.5 seconds
91  }
92 }
93 
95 {
96  window.set_enter_disabled(true);
97  window.get_canvas(0).set_variable("outro_text", wfl::variant(*current_text_));
98 
99  connect_signal_on_draw(window, std::bind(&outro::draw_callback, this));
100 }
101 
103 {
104  /* If we've faded fully in...
105  *
106  * NOTE: we want fading to take around half a second. Given this function runs about every 3 frames, we
107  * limit ourselves to a reasonable 10 fade steps with an alpha difference (rounded up) of 25.5 each cycle.
108  * The actual calculation for alpha is done in the window definition in WFL.
109  */
110  if(fading_in_ && fade_step_ > 10) {
111  // Schedule the fadeout after the provided delay.
112  if(timer_id_ == 0) {
113  timer_id_ = add_timer(duration_, [this](std::size_t) { fading_in_ = false; });
114  }
115 
116  return;
117  }
118 
119  canvas& window_canvas = get_window()->get_canvas(0);
120 
121  // If we've faded fully out...
122  if(!fading_in_ && fade_step_ < 0) {
123  std::advance(current_text_, 1);
124 
125  // ...and we've just showed the last text bit, close the window.
126  if(current_text_ == text_.end()) {
127  get_window()->close();
128  return;
129  }
130 
131  // ...else show the next bit.
132  window_canvas.set_variable("outro_text", wfl::variant(*current_text_));
133 
134  fading_in_ = true;
135  fade_step_ = 0;
136 
138  timer_id_ = 0;
139  }
140 
141  window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
142  window_canvas.set_is_dirty(true);
143 
144  get_window()->set_is_dirty(true);
145 
146  if(fading_in_) {
147  fade_step_++;
148  } else {
149  fade_step_--;
150  }
151 }
152 
153 void outro::post_show(window& /*window*/)
154 {
156  timer_id_ = 0;
157 }
158 
159 } // namespace dialogs
void close()
Requests to close the window.
Definition: window.hpp:181
std::vector< std::string > text_
Definition: outro.hpp:49
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:88
const credits_data & get_credits_data()
Gets all credits data.
Definition: about.cpp:94
unsigned int duration_
Definition: outro.hpp:52
void set_variable(const std::string &key, const wfl::variant &value)
Definition: canvas.hpp:167
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.
static std::string _(const char *str)
Definition: gettext.hpp:92
Display credits about all contributors.
std::vector< std::string >::iterator current_text_
Definition: outro.hpp:50
std::size_t timer_id_
Definition: outro.hpp:57
This file contains the settings handling of the widget library.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:465
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:24
void set_is_dirty(const bool is_dirty)
Definition: canvas.hpp:174
std::size_t i
Definition: function.cpp:940
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:102
canvas & get_canvas(const unsigned index)
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: outro.cpp:153
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:64
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: outro.cpp:94
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
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:285