The Battle for Wesnoth  1.17.23+dev
outro.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2023
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  : modal_dialog(window_id())
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  if(info.end_credits) {
51  text_.push_back("<span size='large'>" + info.campaign_name + "</span>");
52 
53  if(const auto campaign_credits = about::get_campaign_credits(info.campaign)) {
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 {
98 }
99 
101 {
102  /* If we've faded fully in...
103  *
104  * NOTE: we want fading to take around half a second. Given this function runs about every 3 frames, we
105  * limit ourselves to a reasonable 10 fade steps with an alpha difference (rounded up) of 25.5 each cycle.
106  * The actual calculation for alpha is done in the window definition in WFL.
107  */
108  if(fading_in_ && fade_step_ > 10) {
109  // Schedule the fadeout after the provided delay.
110  if(timer_id_ == 0) {
111  timer_id_ = add_timer(duration_, [this](std::size_t) { fading_in_ = false; });
112  }
113 
114  return;
115  }
116 
117  canvas& window_canvas = window::get_canvas(0);
118 
119  // If we've faded fully out...
120  if(!fading_in_ && fade_step_ < 0) {
121  std::advance(current_text_, 1);
122 
123  // ...and we've just showed the last text bit, close the window.
124  if(current_text_ == text_.end()) {
125  window::close();
126  return;
127  }
128 
129  // ...else show the next bit.
130  window_canvas.set_variable("outro_text", wfl::variant(*current_text_));
131 
132  fading_in_ = true;
133  fade_step_ = 0;
134 
136  timer_id_ = 0;
137  }
138 
139  window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
140  window_canvas.update_size_variables();
141  queue_redraw();
142 
143  if(fading_in_) {
144  fade_step_++;
145  } else {
146  fade_step_--;
147  }
148 }
149 
150 void outro::post_show(window& /*window*/)
151 {
153  timer_id_ = 0;
154 }
155 
156 } // namespace dialogs
A simple canvas which can be drawn upon.
Definition: canvas.hpp:45
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:154
void update_size_variables()
Update WFL size variables.
Definition: canvas.cpp:643
Abstract base class for all modal dialogs.
Dialog to display 'The End' at the end of a campaign.
Definition: outro.hpp:26
std::vector< std::string >::iterator current_text_
Definition: outro.hpp:54
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: outro.cpp:150
virtual void update() override
Displays a simple fading screen with any user-provided text.
Definition: outro.cpp:100
unsigned int duration_
Definition: outro.hpp:56
std::vector< std::string > text_
Definition: outro.hpp:53
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: outro.cpp:94
std::size_t timer_id_
Definition: outro.hpp:61
canvas & get_canvas(const unsigned index)
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:456
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:67
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
Definition: window.hpp:331
void close()
Requests to close the window.
Definition: window.hpp:227
std::size_t i
Definition: function.cpp:968
static std::string _(const char *str)
Definition: gettext.hpp:93
This file contains the window object, this object is a top level container which has the event manage...
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
Display credits about all contributors.
std::optional< credits_data::const_iterator > get_campaign_credits(const std::string &campaign)
Gets credits for a given campaign.
Definition: about.cpp:99
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
bool remove_timer(const std::size_t id)
Removes a timer.
Definition: timer.cpp:168
logger & info()
Definition: log.cpp:238
This file contains the settings handling of the widget library.
Contains the gui2 timer routines.