The Battle for Wesnoth  1.19.17+dev
part.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2025
3  by Iris Morelle <shadowm2006@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 /**
17  * @file
18  * Storyscreen parts and floating images representation.
19  */
20 
21 #include "storyscreen/part.hpp"
22 
23 #include "config.hpp"
24 #include "variable.hpp"
25 
26 namespace storyscreen
27 {
29  : file_(cfg["file"])
30  , x_(cfg["x"].to_int())
31  , y_(cfg["y"].to_int())
32  , delay_(cfg["delay"].to_int())
33  , resize_with_background_(cfg["resize_with_background"].to_bool())
34  , centered_(cfg["centered"].to_bool())
35 {
36 }
37 
39  : scale_horizontally_(true)
40  , scale_vertically_(true)
41  , tile_horizontally_(false)
42  , tile_vertically_(false)
43  , keep_aspect_ratio_(true)
44  , is_base_layer_(false)
45  , image_file_()
46 {
47 }
48 
50  : scale_horizontally_(true)
51  , scale_vertically_(true)
52  , tile_horizontally_(false)
53  , tile_vertically_(false)
54  , keep_aspect_ratio_(true)
55  , is_base_layer_(false)
56  , image_file_()
57 {
58  if(cfg.has_attribute("image")) {
59  image_file_ = cfg["image"].str();
60  }
61 
62  if(cfg.has_attribute("scale")) {
63  scale_vertically_ = cfg["scale"].to_bool(true);
64  scale_horizontally_ = cfg["scale"].to_bool(true);
65  } else {
66  if(cfg.has_attribute("scale_vertically")) {
67  scale_vertically_ = cfg["scale_vertically"].to_bool(true);
68  }
69 
70  if(cfg.has_attribute("scale_horizontally")) {
71  scale_horizontally_ = cfg["scale_horizontally"].to_bool(true);
72  }
73  }
74 
75  if(cfg.has_attribute("tile")) {
76  tile_vertically_ = cfg["tile"].to_bool(false);
77  tile_horizontally_ = cfg["tile"].to_bool(false);
78  } else {
79  if(cfg.has_attribute("tile_vertically")) {
80  tile_vertically_ = cfg["tile_vertically"].to_bool(false);
81  }
82 
83  if(cfg.has_attribute("tile_horizontally")) {
84  tile_horizontally_ = cfg["tile_horizontally"].to_bool(false);
85  }
86  }
87 
88  if(cfg.has_attribute("keep_aspect_ratio")) {
89  keep_aspect_ratio_ = cfg["keep_aspect_ratio"].to_bool(true);
90  }
91 
92  if(cfg.has_attribute("base_layer")) {
93  is_base_layer_ = cfg["base_layer"].to_bool(false);
94  }
95 }
96 
97 part::part(const vconfig& part_cfg)
98  : show_title_()
99  , text_()
100  , text_title_()
101  , text_block_loc_(part::BLOCK_BOTTOM)
102  , text_alignment_("left")
103  , title_alignment_("left")
104  , music_()
105  , sound_()
106  , background_layers_()
107  , floating_images_()
108 {
109  resolve_wml(part_cfg);
110 }
111 
113 {
114  if(s.empty() != true) {
115  if(s == "top") {
116  return part::BLOCK_TOP;
117  } else if(s == "middle") {
118  return part::BLOCK_MIDDLE;
119  }
120  }
121 
122  return part::BLOCK_BOTTOM;
123 }
124 
126 {
127  if(cfg.null()) {
128  return;
129  }
130 
131  // Converts shortcut syntax to members of [background_layer]
132  background_layer bl;
133 
134  if(cfg.has_attribute("background")) {
135  bl.set_file(cfg["background"].str());
136  }
137 
138  if(cfg.has_attribute("scale_background")) {
139  bl.set_scale_horizontally(cfg["scale_background"].to_bool(true));
140  bl.set_scale_vertically(cfg["scale_background"].to_bool(true));
141  } else {
142  if(cfg.has_attribute("scale_background_vertically")) {
143  bl.set_scale_vertically(cfg["scale_background_vertically"].to_bool(true));
144  }
145 
146  if(cfg.has_attribute("scale_background_horizontally")) {
147  bl.set_scale_horizontally(cfg["scale_background_horizontally"].to_bool(true));
148  }
149  }
150 
151  if(cfg.has_attribute("tile_background")) {
152  bl.set_tile_horizontally(cfg["tile_background"].to_bool(false));
153  bl.set_tile_vertically(cfg["tile_background"].to_bool(false));
154  } else {
155  if(cfg.has_attribute("tile_background_vertically")) {
156  bl.set_tile_vertically(cfg["tile_background_vertically"].to_bool(false));
157  }
158 
159  if(cfg.has_attribute("tile_background_horizontally")) {
160  bl.set_tile_vertically(cfg["tile_background_horizontally"].to_bool(false));
161  }
162  }
163 
164  if(cfg.has_attribute("keep_aspect_ratio")) {
165  bl.set_keep_aspect_ratio(cfg["keep_aspect_ratio"].to_bool(true));
166  }
167 
168  background_layers_.push_back(bl);
169 
170  if(cfg.has_attribute("show_title")) {
171  show_title_ = cfg["show_title"].to_bool();
172  }
173 
174  if(cfg.has_attribute("story")) {
175  text_ = cfg["story"].str();
176  }
177 
178  if(cfg.has_attribute("title")) {
179  text_title_ = cfg["title"].str();
180  if(!cfg.has_attribute("show_title")) {
181  show_title_ = true;
182  }
183  }
184 
185  if(cfg.has_attribute("text_layout")) {
186  text_block_loc_ = string_tblock_loc(cfg["text_layout"]);
187  }
188 
189  if(cfg.has_attribute("text_alignment")) {
190  text_alignment_ = cfg["text_alignment"].str();
191  }
192 
193  const auto decode_hposition = [](const std::string& pos_str) {
194  if(pos_str == "left") {
195  return 0;
196  } else if (pos_str == "center") {
197  return 50;
198  } else if (pos_str == "right") {
199  return 100;
200  } else {
201  return 0;
202  }
203  };
204 
205  const auto decode_vposition = [&loc = text_block_loc_](const std::string& pos_str) {
206  // The ternary checks avoid part text and title text overlaping.
207  if(pos_str == "top") {
208  return loc == BLOCK_TOP ? 50 : 0;
209  } else if (pos_str == "middle") {
210  return loc == BLOCK_MIDDLE ? 0 : 50;
211  } else if (pos_str == "bottom") {
212  return loc == BLOCK_BOTTOM ? 50 : 100;
213  } else {
214  return 0;
215  }
216  };
217 
218  if(cfg.has_attribute("title_position")) {
219  if(cfg["title_position"] == "centered") {
220  title_perc_pos_ = {50, 50};
221  } else {
222  const auto vals = utils::split(cfg["title_position"]);
223  switch(vals.size()) {
224  case 0:
225  // No values provided. Default to top-left.
226  title_perc_pos_ = {0, 0};
227  break;
228 
229  case 1:
230  // Singe value, could be either horizontal or vertical.
231  title_perc_pos_ = {decode_hposition(vals[0]), decode_vposition(vals[0])};
232  break;
233 
234  default:
235  // Separate horizontal and vertical values.
236  title_perc_pos_ = {decode_hposition(vals[0]), decode_vposition(vals[1])};
237  break;
238  }
239  }
240  }
241 
242  if(cfg.has_attribute("title_alignment")) {
243  title_alignment_ = cfg["title_alignment"].str();
244  }
245 
246  if(cfg.has_attribute("music")) {
247  music_ = cfg["music"].str();
248  }
249 
250  if(cfg.has_attribute("sound")) {
251  sound_ = cfg["sound"].str();
252  }
253 
254  if(cfg.has_attribute("voice")) {
255  voice_ = cfg["voice"].str();
256  }
257 
258  // Inherited
260 }
261 
262 bool part::resolve_wml_helper(const std::string& key, const vconfig& node)
263 {
264  bool found = false;
265 
266  // [background_layer]
267  if(key == "background_layer") {
268  background_layers_.push_back(node.get_parsed_config());
269  found = true;
270  }
271  // [image]
272  else if(key == "image") {
273  floating_images_.push_back(node.get_parsed_config());
274  found = true;
275  }
276 
277  return found;
278 }
279 
280 } // end namespace storyscreen
map_location loc
Definition: move.cpp:172
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:157
bool has_attribute(std::string_view key) const
Definition: config.cpp:156
void set_scale_horizontally(bool b)
Sets whether the layer should be scaled horizontally.
Definition: part.hpp:138
void set_keep_aspect_ratio(bool b)
Sets whether the aspect ratio should be preserved.
Definition: part.hpp:186
void set_tile_vertically(bool b)
Sets whether the layer should be tiled vertically.
Definition: part.hpp:174
void set_file(const std::string &str)
Sets the path to the image file.
Definition: part.hpp:210
void set_tile_horizontally(bool b)
Sets whether the layer should be tiled horizontally.
Definition: part.hpp:162
void set_scale_vertically(bool b)
Sets whether the layer should be scaled vertically.
Definition: part.hpp:150
floating_image(const config &cfg)
WML-based constructor.
Definition: part.cpp:28
Represents and contains information about a single storyscreen part.
Definition: part.hpp:229
std::string voice_
Definition: part.hpp:359
point title_perc_pos_
Definition: part.hpp:362
static BLOCK_LOCATION string_tblock_loc(const std::string &s)
Definition: part.cpp:112
BLOCK_LOCATION text_block_loc_
Definition: part.hpp:353
std::string text_title_
Definition: part.hpp:352
std::string text_
Definition: part.hpp:351
std::vector< floating_image > floating_images_
Definition: part.hpp:365
part(const vconfig &part_cfg)
Constructs a storyscreen part from a managed WML node.
Definition: part.cpp:97
std::string title_alignment_
Definition: part.hpp:355
std::vector< background_layer > background_layers_
Definition: part.hpp:364
std::string music_
Definition: part.hpp:357
std::string text_alignment_
Definition: part.hpp:354
std::string sound_
Definition: part.hpp:358
virtual void resolve_wml(const vconfig &cfg) override
Inherited from story_parser.
Definition: part.cpp:125
virtual bool resolve_wml_helper(const std::string &key, const vconfig &node) override
Inherited from story_parser.
Definition: part.cpp:262
BLOCK_LOCATION
Currently used to indicate where the text block should be placed.
Definition: part.hpp:236
@ BLOCK_BOTTOM
Bottom of the screen.
Definition: part.hpp:239
@ BLOCK_MIDDLE
Center of the screen.
Definition: part.hpp:238
@ BLOCK_TOP
Top of the screen.
Definition: part.hpp:237
bool show_title_
Definition: part.hpp:350
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:29
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
config get_parsed_config() const
Definition: variable.cpp:177
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
std::vector< std::string > split(const config_attribute_value &val)
Storyscreen parts and floating images representation.
static map_location::direction s