1 /*
2    Copyright (C) 2009 - 2018 by Iris Morelle <shadowm2006@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 /**
16  * @file
17  * Storyscreen parts and floating images representation.
18  */
19 
20 #pragma once
21 
22 #include "storyscreen/parser.hpp"
23 
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 class config;
29 class vconfig;
30 
31 namespace storyscreen
32 {
33 /**
34  * Represents and contains information about image labels used
35  * in story screen parts.
36  */
37 class floating_image
38 {
39 public:
40 	/**
41 	 * WML-based constructor.
42 	 * @param cfg Object corresponding to a [image] block's contents from
43 	 *            a [part] node.
44 	 */
45 	floating_image(const config& cfg);
46 
47 	/**
48 	 * Copy constructor.
49 	 */
50 	floating_image(const floating_image& fi);
51 
operator =(const floating_image & fi)52 	floating_image& operator=(const floating_image& fi)
53 	{
54 		assign(fi);
55 		return *this;
56 	}
57 
file() const58 	std::string file() const
59 	{
60 		return file_;
61 	}
62 
63 	/**
64 	 * Returns the referential X coordinate of the image.
65 	 * The actual (corrected) value is determined at render time.
66 	 */
ref_x() const67 	int ref_x() const
68 	{
69 		return x_;
70 	}
71 
72 	/**
73 	 * Returns the referential Y coordinate of the image.
74 	 * The actual (corrected) value is determined at render time.
75 	 */
ref_y() const76 	int ref_y() const
77 	{
78 		return y_;
79 	}
80 
81 	/**
82 	 * Whether the image should be automatically scaled as much as
83 	 * the storyscreen background is.
84 	 */
autoscale() const85 	bool autoscale() const
86 	{
87 		return autoscaled_;
88 	}
89 
90 	/**
91 	 * Whether the image coordinates specify the location of its
92 	 * center (true) or top-left corner (false).
93 	 */
centered() const94 	bool centered() const
95 	{
96 		return centered_;
97 	}
98 
99 	/** Delay before displaying, in milliseconds. */
display_delay() const100 	int display_delay() const
101 	{
102 		return delay_;
103 	}
104 
105 private:
106 	std::string file_;
107 	int x_, y_; // referential (non corrected) x,y
108 	int delay_;
109 	bool autoscaled_;
110 	bool centered_;
111 
112 	/** Copy constructor and operator=() implementation details. */
113 	void assign(const floating_image& fi);
114 };
115 
116 class background_layer
117 {
118 public:
119 	background_layer();
120 
121 	/**
122 	 * Constructor. Initializes a background_layer object from a
123 	 * [background_layer] WML node.
124 	 */
125 	background_layer(const config& cfg);
126 
127 	/** Whether the layer should be scaled horizontally. */
scale_horizontally() const128 	bool scale_horizontally() const
129 	{
130 		return scale_horizontally_;
131 	}
132 
133 	/** Sets whether the layer should be scaled horizontally. */
set_scale_horizontally(bool b)134 	void set_scale_horizontally(bool b)
135 	{
136 		scale_horizontally_ = b;
137 	}
138 
139 	/** Whether the layer should be scaled vertically. */
scale_vertically() const140 	bool scale_vertically() const
141 	{
142 		return scale_vertically_;
143 	}
144 
145 	/** Sets whether the layer should be scaled vertically. */
set_scale_vertically(bool b)146 	void set_scale_vertically(bool b)
147 	{
148 		scale_vertically_ = b;
149 	}
150 
151 	/** Whether the layer should be tiled horizontally. */
tile_horizontally() const152 	bool tile_horizontally() const
153 	{
154 		return tile_horizontally_;
155 	}
156 
157 	/** Sets whether the layer should be tiled horizontally. */
set_tile_horizontally(bool b)158 	void set_tile_horizontally(bool b)
159 	{
160 		tile_horizontally_ = b;
161 	}
162 
163 	/** Whether the layer should be tiled vertically. */
tile_vertically() const164 	bool tile_vertically() const
165 	{
166 		return tile_vertically_;
167 	}
168 
169 	/** Sets whether the layer should be tiled vertically. */
set_tile_vertically(bool b)170 	void set_tile_vertically(bool b)
171 	{
172 		tile_vertically_ = b;
173 	}
174 
175 	/** Whether the aspect ratio should be preserved while scaling. */
keep_aspect_ratio() const176 	bool keep_aspect_ratio() const
177 	{
178 		return keep_aspect_ratio_;
179 	}
180 
181 	/** Sets whether the aspect ratio should be preserved. */
set_keep_aspect_ratio(bool b)182 	void set_keep_aspect_ratio(bool b)
183 	{
184 		keep_aspect_ratio_ = b;
185 	}
186 
187 	/** Whether is this layer the base layer. */
is_base_layer() const188 	bool is_base_layer() const
189 	{
190 		return is_base_layer_;
191 	}
192 
193 	/** Sets whether is this layer a base layer. */
set_base_layer(bool b)194 	void set_base_layer(bool b)
195 	{
196 		is_base_layer_ = b;
197 	}
198 
199 	/** The path to the file to load the image from. */
file() const200 	const std::string& file() const
201 	{
202 		return image_file_;
203 	}
204 
205 	/** Sets the path to the image file. */
set_file(const std::string & str)206 	void set_file(const std::string& str)
207 	{
208 		image_file_ = str;
209 	}
210 
211 private:
212 	bool scale_horizontally_;
213 	bool scale_vertically_;
214 	bool tile_horizontally_;
215 	bool tile_vertically_;
216 	bool keep_aspect_ratio_;
217 	bool is_base_layer_;
218 	std::string image_file_;
219 };
220 
221 /**
222  * Represents and contains information about a single storyscreen part.
223  */
224 class part : private story_parser
225 {
226 public:
227 	/**
228 	 * Currently used to indicate where the text block should be placed.
229 	 * Note that it will always take as much space as it is
230 	 * possible horizontally.
231 	 */
232 	enum BLOCK_LOCATION {
233 		BLOCK_TOP,    /**< Top of the screen. */
234 		BLOCK_MIDDLE, /**< Center of the screen. */
235 		BLOCK_BOTTOM  /**< Bottom of the screen. This is the default. */
236 	};
237 
238 	/**
239 	 * Used to signal user actions.
240 	 */
241 	enum RESULT {
242 		NEXT, /**< Jump to next story part. */
243 		SKIP, /**< Skip all story parts for this set. */
244 		QUIT  /**< Quit game and go back to main menu. */
245 	};
246 
247 	/**
248 	 * Constructs a storyscreen part from a managed WML node.
249 	 * @param part_cfg Node object which should correspond to a [part] block's contents.
250 	 */
251 	part(const vconfig& part_cfg);
252 
253 	/** Whether the story screen title should be displayed or not. */
show_title() const254 	bool show_title() const
255 	{
256 		return show_title_;
257 	}
258 
259 	/** Retrieves the story text itself. */
text() const260 	const std::string& text() const
261 	{
262 		return text_;
263 	}
264 
265 	/** Changes the story text. */
set_text(const std::string & text)266 	void set_text(const std::string& text)
267 	{
268 		text_ = text;
269 	}
270 
271 	/** Retrieves the story screen title. */
title() const272 	const std::string& title() const
273 	{
274 		return text_title_;
275 	}
276 
277 	/** Changes the story screen title. */
set_title(const std::string & title)278 	void set_title(const std::string& title)
279 	{
280 		text_title_ = title;
281 	}
282 
283 	/** Retrieves the background music. */
music() const284 	const std::string& music() const
285 	{
286 		return music_;
287 	}
288 
289 	/** Retrieves a one-time-only sound effect. */
sound() const290 	const std::string& sound() const
291 	{
292 		return sound_;
293 	}
294 
295 	/** Retrieves a voice track. */
voice() const296 	const std::string& voice() const
297 	{
298 		return voice_;
299 	}
300 
301 	/** Retrieves the area of the screen on which the story text is displayed. */
story_text_location() const302 	BLOCK_LOCATION story_text_location() const
303 	{
304 		return text_block_loc_;
305 	}
306 
307 	/** Retrieves the alignment of the story text within the text area. */
story_text_alignment() const308 	const std::string& story_text_alignment() const
309 	{
310 		return text_alignment_;
311 	}
312 
313 	/** Retrieves the alignment of the title text against the screen. */
title_text_alignment() const314 	const std::string& title_text_alignment() const
315 	{
316 		return title_alignment_;
317 	}
318 
319 	/** Retrieve any associated floating images for this story screen. */
get_floating_images() const320 	const std::vector<floating_image>& get_floating_images() const
321 	{
322 		return floating_images_;
323 	}
324 
325 	/** Retrieve background layers for this story screen. */
get_background_layers() const326 	const std::vector<background_layer>& get_background_layers() const
327 	{
328 		return background_layers_;
329 	}
330 
331 private:
332 	/** Inherited from story_parser. */
333 	virtual void resolve_wml(const vconfig& cfg) override;
334 
335 	/** Inherited from story_parser. */
336 	virtual bool resolve_wml_helper(const std::string& key, const vconfig& node) override;
337 
338 	static BLOCK_LOCATION string_tblock_loc(const std::string& s);
339 
340 	bool show_title_;
341 	std::string text_;
342 	std::string text_title_;
343 	BLOCK_LOCATION text_block_loc_;
344 	std::string text_alignment_;
345 	std::string title_alignment_;
346 
347 	std::string music_;
348 	std::string sound_;
349 	std::string voice_;
350 
351 	std::vector<background_layer> background_layers_;
352 	std::vector<floating_image> floating_images_;
353 };
354 
355 } // end namespace storyscreen
356