The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
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
26namespace 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
97part::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]
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
262bool 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:157
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
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