The Battle for Wesnoth  1.17.0-dev
outro.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2021
3  by Charles Dang <exodia339@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
18 #include "gui/dialogs/outro.hpp"
19 
20 #include "about.hpp"
21 #include "formula/variant.hpp"
22 #include "game_classification.hpp"
23 #include "gettext.hpp"
25 #include "gui/core/timer.hpp"
26 #include "gui/widgets/settings.hpp"
27 #include "gui/widgets/window.hpp"
28 
29 #include <cmath>
30 
31 namespace gui2::dialogs
32 {
33 REGISTER_DIALOG(outro)
34 
36  : text_()
37  , current_text_()
38  , duration_(info.end_text_duration)
39  , fade_step_(0)
40  , fading_in_(true)
41  , timer_id_(0)
42 {
43  if(!info.end_text.empty()) {
44  text_.push_back(info.end_text);
45  } else {
46  text_.push_back(_("The End"));
47  }
48 
49  if(info.end_credits) {
50  text_.push_back("<span size='large'>" + info.campaign_name + "</span>");
51 
52  if(const auto campaign_credits = about::get_campaign_credits(info.campaign)) {
53  for(const auto& about : (*campaign_credits)->sections) {
54  if(about.names.empty()) {
55  continue;
56  }
57 
58  // Split the names into chunks of 5. Use float for proper ceil function!
59  static const float chunk_size = 5.0;
60 
61  const unsigned num_names = about.names.size();
62  const unsigned num_chunks = std::ceil(num_names / chunk_size);
63 
64  for(std::size_t i = 0; i < num_chunks; ++i) {
65  std::stringstream ss;
66 
67  // Only include section title on first chunk
68  if(i == 0) {
69  ss << about.title << "\n\n";
70  }
71 
72  for(std::size_t k = i * chunk_size; k < std::min<unsigned>((i + 1) * chunk_size, num_names); ++k) {
73  ss << "<span size='xx-small'>" << about.names[k].first << "</span>\n";
74  }
75 
76  // Clean up the trailing newline
77  std::string section_text = ss.str();
78  section_text.pop_back();
79 
80  text_.push_back(std::move(section_text));
81  }
82  }
83  }
84  }
85 
86  current_text_ = text_.begin();
87 
88  if(!duration_) {
89  duration_ = 3500; // 3.5 seconds
90  }
91 }
92 
94 {
95  window.set_enter_disabled(true);
96  window.get_canvas(0).set_variable("outro_text", wfl::variant(*current_text_));
97 
98  connect_signal_on_draw(window, std::bind(&outro::draw_callback, this));
99 }
100 
102 {
103  /* If we've faded fully in...
104  *
105  * NOTE: we want fading to take around half a second. Given this function runs about every 3 frames, we
106  * limit ourselves to a reasonable 10 fade steps with an alpha difference (rounded up) of 25.5 each cycle.
107  * The actual calculation for alpha is done in the window definition in WFL.
108  */
109  if(fading_in_ && fade_step_ > 10) {
110  // Schedule the fadeout after the provided delay.
111  if(timer_id_ == 0) {
112  timer_id_ = add_timer(duration_, [this](std::size_t) { fading_in_ = false; });
113  }
114 
115  return;
116  }
117 
118  canvas& window_canvas = get_window()->get_canvas(0);
119 
120  // If we've faded fully out...
121  if(!fading_in_ && fade_step_ < 0) {
122  std::advance(current_text_, 1);
123 
124  // ...and we've just showed the last text bit, close the window.
125  if(current_text_ == text_.end()) {
126  get_window()->close();
127  return;
128  }
129 
130  // ...else show the next bit.
131  window_canvas.set_variable("outro_text", wfl::variant(*current_text_));
132 
133  fading_in_ = true;
134  fade_step_ = 0;
135 
137  timer_id_ = 0;
138  }
139 
140  window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
141  window_canvas.set_is_dirty(true);
142 
143  get_window()->set_is_dirty(true);
144 
145  if(fading_in_) {
146  fade_step_++;
147  } else {
148  fade_step_--;
149  }
150 }
151 
152 void outro::post_show(window& /*window*/)
153 {
155  timer_id_ = 0;
156 }
157 
158 } // namespace dialogs
void close()
Requests to close the window.
Definition: window.hpp:182
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:168
std::vector< std::string > text_
Definition: outro.hpp:50
logger & info()
Definition: log.cpp:89
unsigned int duration_
Definition: outro.hpp:53
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:93
Display credits about all contributors.
std::vector< std::string >::iterator current_text_
Definition: outro.hpp:51
std::size_t timer_id_
Definition: outro.hpp:58
This file contains the settings handling of the widget library.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:466
A simple canvas which can be drawn upon.
Definition: canvas.hpp:42
Dialog to display &#39;The End&#39; at the end of a campaign.
Definition: outro.hpp:25
void set_is_dirty(const bool is_dirty)
Definition: canvas.hpp:175
std::size_t i
Definition: function.cpp:967
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:127
std::optional< credits_data::const_iterator > get_campaign_credits(const std::string &campaign)
Gets credits for a given campaign.
Definition: about.cpp:100
void draw_callback()
Definition: outro.cpp:101
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:152
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: outro.cpp:93
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:192
bool remove_timer(const std::size_t id)
Removes a timer.
Definition: timer.cpp:168
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
Definition: window.hpp:286