The Battle for Wesnoth  1.19.0-dev
canvas_private.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 - 2024
3  by Mark de Wever <koraq@xs4all.nl>
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 #include "gui/core/canvas.hpp"
18 
19 namespace gui2
20 {
21 /**
22  * @ingroup GUICanvasWML
23  *
24  * Definition of a line.
25  * When drawing a line it doesn't get blended on the surface but replaces the pixels instead.
26  * A blitting flag might be added later if needed.
27  *
28  * Keys:
29  * Key |Type |Default |Description
30  * -------------|----------------------------------------|---------|-----------
31  * x1 | @ref guivartype_f_unsigned "f_unsigned"|0 |The x coordinate of the startpoint.
32  * y1 | @ref guivartype_f_unsigned "f_unsigned"|0 |The y coordinate of the startpoint.
33  * x2 | @ref guivartype_f_unsigned "f_unsigned"|0 |The x coordinate of the endpoint.
34  * y2 | @ref guivartype_f_unsigned "f_unsigned"|0 |The y coordinate of the endpoint.
35  * color | @ref guivartype_color "color" |"" |The color of the line.
36  * thickness | @ref guivartype_unsigned "unsigned" |0 |The thickness of the line; if 0 nothing is drawn.
37  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation this message is not stored.
38  *
39  * Variables:
40  * Key |Type |Description
41  * -------------------|----------------------------------------|-----------
42  * width | @ref guivartype_unsigned "unsigned" |The width of the canvas.
43  * height | @ref guivartype_unsigned "unsigned" |The height of the canvas.
44  * text | @ref guivartype_t_string "t_string" |The text to render on the widget.
45  * text_maximum_width | @ref guivartype_unsigned "unsigned" |The maximum width available for the text on the widget.
46  * text_maximum_height| @ref guivartype_unsigned "unsigned" |The maximum height available for the text on the widget.
47  * text_wrap_mode | @ref guivartype_int "int" |When the text doesn't fit in the available width there are several ways to fix that. This variable holds the best method. (NOTE this is a 'hidden' variable meant to copy state from a widget to its canvas so there's no reason to use this variable and thus its values are not listed and might change without further notice.)
48  * text_alignment | @ref guivartype_h_align "h_align" |The way the text is aligned inside the canvas.
49  *
50  * The size variables are copied to the window and will be determined at runtime.
51  * This is needed since the main window can be resized and the dialog needs to resize accordingly.
52  * The following variables are available:
53  * Key |Type |Description
54  * ---------------|------------------------------------|-----------
55  * screen_width | @ref guivartype_unsigned "unsigned"|The usable width of the Wesnoth main window.
56  * screen_height | @ref guivartype_unsigned "unsigned"|The usable height of the Wesnoth main window.
57  * gamemapx_offset| @ref guivartype_unsigned "unsigned"|The distance between left edge of the screen and the game map.
58  * gamemap_width | @ref guivartype_unsigned "unsigned"|The usable width of the Wesnoth gamemap, if no gamemap shown it's the same value as screen_width.
59  * gamemap_height | @ref guivartype_unsigned "unsigned"|The usable height of the Wesnoth gamemap, if no gamemap shown it's the same value as screen_height.
60  * mouse_x | @ref guivartype_unsigned "unsigned"|The x coordinate of the mouse pointer.
61  * mouse_y | @ref guivartype_unsigned "unsigned"|The y coordinate of the mouse pointer.
62  * window_width | @ref guivartype_unsigned "unsigned"|The window width. This value has two meanings during the layout phase. This only applies if automatic placement is not enabled. - When set to 0 it should return the wanted maximum width. If no maximum is wanted it should be set to the '"(screen_width)"'. - When not equal to 0 its value is the best width for the window. When the size should remain unchanged it should be set to '"(window_width)"'.
63  * window_height | @ref guivartype_unsigned "unsigned"|The window height. This value has two meanings during the layout phase. This only applies if automatic placement is not enabled. - When set to 0 it should return the wanted maximum height. If no maximum is wanted it should be set to the '"(screen_height)"'. - When not equal to 0 its value is the best height for the window. When the size should remain unchanged it should be set to '"(window_height)"'.
64  *
65  * Note when drawing the valid coordinates are:
66  * * 0 -> width - 1
67  * * 0 -> height -1
68  *
69  * Drawing outside this area will result in unpredictable results including crashing. (That should be fixed, when encountered.)
70  */
71 class line_shape : public canvas::shape
72 {
73 public:
74  /**
75  * Constructor.
76  *
77  * @param cfg The config object to define the line.
78  */
79  explicit line_shape(const config& cfg);
80 
81  void draw(wfl::map_formula_callable& variables) override;
82 
83 private:
84  typed_formula<unsigned> x1_; /**< The start x coordinate of the line. */
85  typed_formula<unsigned> y1_; /**< The start y coordinate of the line. */
86  typed_formula<unsigned> x2_; /**< The end x coordinate of the line. */
87  typed_formula<unsigned> y2_; /**< The end y coordinate of the line. */
88 
89  /** The color of the line. */
91 
92  /**
93  * The thickness of the line.
94  *
95  * if the value is odd the x and y are the middle of the line.
96  * if the value is even the x and y are the middle of a line
97  * with width - 1. (0 is special case, does nothing.)
98  */
99  unsigned thickness_;
100 };
101 
102 /**
103  * @ingroup GUICanvasWML
104  *
105  * Class holding common attribute names (for WML) and common implementation (in C++) for shapes
106  * placed with the 4 attributes x, y, w and h.
107  *
108  * Keys:
109  * Key |Type |Default|Description
110  * -------------------|----------------------------------------|-------|-----------
111  * x | @ref guivartype_f_unsigned "f_unsigned"|0 |The x coordinate of the top left corner.
112  * y | @ref guivartype_f_unsigned "f_unsigned"|0 |The y coordinate of the top left corner.
113  * w | @ref guivartype_f_unsigned "f_unsigned"|0 |The width of the rectangle.
114  * h | @ref guivartype_f_unsigned "f_unsigned"|0 |The height of the rectangle.
115  */
117 {
118 protected:
119  /**
120  * Constructor.
121  *
122  * @param cfg The config object to define the rectangle.
123  */
124  explicit rect_bounded_shape(const config& cfg)
125  : shape(cfg)
126  , x_(cfg["x"])
127  , y_(cfg["y"])
128  , w_(cfg["w"])
129  , h_(cfg["h"])
130  {
131  }
132 
133  typed_formula<int> x_; /**< The x coordinate of the rectangle. */
134  typed_formula<int> y_; /**< The y coordinate of the rectangle. */
135  typed_formula<int> w_; /**< The width of the rectangle. */
136  typed_formula<int> h_; /**< The height of the rectangle. */
137 };
138 
139 /**
140  * @ingroup GUICanvasWML
141  *
142  * Definition of a rectangle.
143  * When drawing a rectangle it doesn't get blended on the surface but replaces the pixels instead.
144  * A blitting flag might be added later if needed.
145  *
146  * Keys:
147  * Key |Type |Default|Description
148  * -------------------|----------------------------------------|-------|-----------
149  * border_thickness | @ref guivartype_unsigned "unsigned" |0 |The thickness of the border if the thickness is zero it's not drawn.
150  * border_color | @ref guivartype_color "color" |"" |The color of the border if empty it's not drawn.
151  * fill_color | @ref guivartype_color "color" |"" |The color of the interior if omitted it's not drawn.
152  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation this message is not stored.
153  *
154  * Variables: see line_shape
155  */
157 {
158 public:
159  /**
160  * Constructor.
161  *
162  * @param cfg The config object to define the rectangle.
163  */
164  explicit rectangle_shape(const config& cfg);
165 
166  void draw(wfl::map_formula_callable& variables) override;
167 
168 private:
169  /**
170  * Border thickness.
171  *
172  * If 0 the fill color is used for the entire widget.
173  */
175 
176  /**
177  * The border color of the rectangle.
178  *
179  * If the color is fully transparent the border isn't drawn.
180  */
182 
183  /**
184  * The border color of the rectangle.
185  *
186  * If the color is fully transparent the rectangle won't be filled.
187  */
189 };
190 
191 /**
192  * @ingroup GUICanvasWML
193  *
194  * Definition of a rounded rectangle shape.
195  * When drawing a rounded rectangle it doesn't get blended on the surface but replaces the pixels instead.
196  * A blitting flag might be added later if needed.
197  * Key |Type |Default |Description
198  * ----------------|----------------------------------------|---------|-----------
199  * corner_radius | @ref guivartype_f_unsigned "f_unsigned"|0 |The radius of the rectangle's corners.
200  * border_thickness| @ref guivartype_unsigned "unsigned" |0 |The thickness of the border; if the thickness is zero it's not drawn.
201  * border_color | @ref guivartype_color "color" |"" |The color of the border; if empty it's not drawn.
202  * fill_color | @ref guivartype_color "color" |"" |The color of the interior; if omitted it's not drawn.
203  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation; this message is not stored.
204  */
206 {
207 public:
208  /**
209  * Constructor.
210  *
211  * @param cfg The config object to define the round rectangle.
212  */
213  explicit round_rectangle_shape(const config& cfg);
214 
215  void draw(wfl::map_formula_callable& variables) override;
216 
217 private:
218  typed_formula<int> r_; /**< The radius of the corners. */
219 
220  /**
221  * Border thickness.
222  *
223  * If 0 the fill color is used for the entire widget.
224  */
226 
227  /**
228  * The border color of the rounded rectangle.
229  *
230  * If the color is fully transparent the border isn't drawn.
231  */
233 
234  /**
235  * The border color of the rounded rectangle.
236  *
237  * If the color is fully transparent the rounded rectangle won't be filled.
238  */
240 };
241 
242 /**
243  * @ingroup GUICanvasWML
244  *
245  * Definition of a circle.
246  * When drawing a circle it doesn't get blended on the surface but replaces the pixels instead.
247  * A blitting flag might be added later if needed.
248  *
249  * Keys:
250  * Key |Type |Default|Description
251  * -------------------|----------------------------------------|-------|-----------
252  * x | @ref guivartype_f_unsigned "f_unsigned"|0 |The x coordinate of the center.
253  * y | @ref guivartype_f_unsigned "f_unsigned"|0 |The y coordinate of the center.
254  * radius | @ref guivartype_f_unsigned "f_unsigned"|0 |The radius of the circle; if 0 nothing is drawn.
255  * color | @ref guivartype_color "color" |"" |The color of the circle.
256  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation this message is not stored.
257  *
258  * Variables: see line_shape
259  *
260  * Drawing outside the area will result in unpredictable results including crashing. (That should be fixed, when encountered.)
261  */
263 {
264 public:
265  /**
266  * Constructor.
267  *
268  * @param cfg The config object to define the circle.
269  */
270  explicit circle_shape(const config& cfg);
271 
272  void draw( wfl::map_formula_callable& variables) override;
273 
274 private:
275  typed_formula<unsigned> x_; /**< The center x coordinate of the circle. */
276  typed_formula<unsigned> y_; /**< The center y coordinate of the circle. */
277 
278  /** The radius of the circle. */
280 
281  /** The border color of the circle. */
283 
284  /** The fill color of the circle. */
286 
287  /** The border thickness of the circle. */
288  unsigned int border_thickness_;
289 };
290 
291 /**
292  * @ingroup GUICanvasWML
293  *
294  * Keys:
295  * Key |Type |Default|Description
296  * -------------------|------------------------------------------|-------|-----------
297  * x | @ref guivartype_f_unsigned "f_unsigned" |0 |The x coordinate of the top left corner.
298  * y | @ref guivartype_f_unsigned "f_unsigned" |0 |The y coordinate of the top left corner.
299  * w | @ref guivartype_f_unsigned "f_unsigned" |0 |The width of the image, if not zero the image will be scaled to the desired width.
300  * h | @ref guivartype_f_unsigned "f_unsigned" |0 |The height of the image, if not zero the image will be scaled to the desired height.
301  * resize_mode | @ref guivartype_resize_mode "resize_mode"|scale |Determines how an image is scaled to fit the wanted size.
302  * vertical_mirror | @ref guivartype_f_bool "f_bool" |false |Mirror the image over the vertical axis.
303  * name | @ref guivartype_string "string" |"" |The name of the image.
304  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation this message is not stored.
305  *
306  * Variables:
307  * Key |Type |Description
308  * ---------------------|--------------------------------------|-----------
309  * image_width | @ref guivartype_unsigned "unsigned" |The width of the image, either the requested width or the natural width of the image. This value can be used to set the x (or y) value of the image. (This means x and y are evaluated after the width and height.)
310  * image_height | @ref guivartype_unsigned "unsigned" |The height of the image, either the requested height or the natural height of the image. This value can be used to set the y (or x) value of the image. (This means x and y are evaluated after the width and height.)
311  * image_original_width | @ref guivartype_unsigned "unsigned" |The width of the image as stored on disk, can be used to set x or w (also y and h can be set).
312  * image_original_height| @ref guivartype_unsigned "unsigned" |The height of the image as stored on disk, can be used to set y or h (also x and y can be set).
313  *
314  * Also the general variables are available, see line_shape
315  */
317 {
318 public:
319  /**
320  * Constructor.
321  *
322  * @param cfg The config object to define the image.
323  * @param functions WFL functions to execute.
324  */
325  image_shape(const config& cfg, wfl::action_function_symbol_table& functions);
326 
327  void draw(wfl::map_formula_callable& variables) override;
328 
329 private:
330  typed_formula<unsigned> x_; /**< The x coordinate of the image. */
331  typed_formula<unsigned> y_; /**< The y coordinate of the image. */
332  typed_formula<unsigned> w_; /**< The width of the image. */
333  typed_formula<unsigned> h_; /**< The height of the image. */
334 
335  /**
336  * Name of the image.
337  *
338  * This value is only used when the image name is a formula. If it isn't a
339  * formula the image will be loaded in the constructor. If it's a formula it
340  * will be loaded every draw cycles. This allows 'changing' images.
341  */
343 
344  /**
345  * Determines the way an image will be resized.
346  *
347  * If the image is smaller is needed it needs to resized, how is determined
348  * by the value of this enum.
349  */
350  enum class resize_mode {
351  scale,
352  scale_sharp,
353  stretch,
354  tile,
355  tile_center,
356  tile_highres,
357  };
358 
359  /** Converts a string to a resize mode. */
360  resize_mode get_resize_mode(const std::string& resize_mode);
361 
362  /** The resize mode for an image. */
364 
365  /** Mirror the image over the vertical axis. */
367 
368  // TODO: use a typed_formula?
370 
371  static void dimension_validation(unsigned value, const std::string& name, const std::string& key);
372 };
373 
374 /**
375  * @ingroup GUICanvasWML
376  *
377  * Key |Type |Default |Description
378  * -------------------|------------------------------------------|---------|-----------
379  * font_family | @ref guivartype_font_style "font_style" |"sans" |The font family used for the text.
380  * font_size | @ref guivartype_f_unsigned "f_unsigned" |mandatory|The size of the text font.
381  * font_style | @ref guivartype_f_unsigned "f_unsigned" |"" |The style of the text.
382  * text_alignment | @ref guivartype_f_unsigned "f_unsigned" |"left" |The alignment of the text.
383  * color | @ref guivartype_color "color" |"" |The color of the text.
384  * text | @ref guivartype_f_tstring "f_tstring" |"" |The text to draw (translatable).
385  * text_markup | @ref guivartype_f_bool "f_bool" |false |Can the text have mark-up?
386  * text_link_aware | @ref guivartype_f_bool "f_bool" |false |Is the text link aware?
387  * text_link_color | @ref guivartype_string "string" |"#ffff00"|The color of links in the text.
388  * maximum_width | @ref guivartype_f_int "f_int" |-1 |The maximum width the text is allowed to be.
389  * maximum_height | @ref guivartype_f_int "f_int" |-1 |The maximum height the text is allowed to be.
390  * debug | @ref guivartype_string "string" |"" |Debug message to show upon creation this message is not stored.
391  *
392  * NOTE alignment could only be done with the formulas, but now with the text_alignment flag as well,
393  * older widgets might still use the formulas and not all widgets may expose the text alignment yet and when exposed not use it yet.
394  *
395  * Variables:
396  * Key |Type |Description
397  * -------------------|------------------------------------------|-----------
398  * text_width | @ref guivartype_unsigned "unsigned" |The width of the rendered text.
399  * text_height | @ref guivartype_unsigned "unsigned" |The height of the rendered text.
400  * Also the general variables are available, see line_shape
401  */
403 {
404 public:
405  /**
406  * Constructor.
407  *
408  * @param cfg The config object to define the text.
409  */
410  explicit text_shape(const config& cfg);
411 
412  void draw(wfl::map_formula_callable& variables) override;
413 
414 private:
415  /** The text font family. */
417 
418  /** The font size of the text. */
420 
421  /** The style of the text. */
423 
424  /** The alignment of the text. */
426 
427  /** The color of the text. */
429 
430  /** The text to draw. */
432 
433  /** The text markup switch of the text. */
435 
436  /** The link aware switch of the text. */
438 
439  /** The link color of the text. */
441 
442  /** The maximum width for the text. */
444 
445  /** The number of characters per line. */
447 
448  /** The maximum height for the text. */
450 
451  /** Start and end offsets for highlight */
454 
455  /** The color to be used for highlighting */
457 
458  /** Whether to apply a text outline. */
460 };
461 
462 }
This file contains the canvas object which is the part where the widgets draw (temporally) images on.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
Abstract base class for all other shapes.
Definition: canvas.hpp:53
shape(const config &cfg)
Definition: canvas.hpp:55
Definition of a circle.
typed_formula< color_t > border_color_
The border color of the circle.
typed_formula< unsigned > x_
The center x coordinate of the circle.
typed_formula< unsigned > radius_
The radius of the circle.
unsigned int border_thickness_
The border thickness of the circle.
circle_shape(const config &cfg)
Constructor.
Definition: canvas.cpp:210
typed_formula< color_t > fill_color_
The fill color of the circle.
typed_formula< unsigned > y_
The center y coordinate of the circle.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:225
typed_formula< std::string > image_name_
Name of the image.
resize_mode
Determines the way an image will be resized.
typed_formula< unsigned > w_
The width of the image.
resize_mode get_resize_mode(const std::string &resize_mode)
Converts a string to a resize mode.
Definition: canvas.cpp:368
typed_formula< unsigned > x_
The x coordinate of the image.
static void dimension_validation(unsigned value, const std::string &name, const std::string &key)
Definition: canvas.cpp:269
typed_formula< unsigned > y_
The y coordinate of the image.
typed_formula< unsigned > h_
The height of the image.
resize_mode resize_mode_
The resize mode for an image.
wfl::formula actions_formula_
typed_formula< bool > mirror_
Mirror the image over the vertical axis.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:278
image_shape(const config &cfg, wfl::action_function_symbol_table &functions)
Constructor.
Definition: canvas.cpp:252
Definition of a line.
typed_formula< color_t > color_
The color of the line.
typed_formula< unsigned > x1_
The start x coordinate of the line.
typed_formula< unsigned > y1_
The start y coordinate of the line.
unsigned thickness_
The thickness of the line.
typed_formula< unsigned > x2_
The end x coordinate of the line.
line_shape(const config &cfg)
Constructor.
Definition: canvas.cpp:47
typed_formula< unsigned > y2_
The end y coordinate of the line.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:62
Class holding common attribute names (for WML) and common implementation (in C++) for shapes placed w...
typed_formula< int > x_
The x coordinate of the rectangle.
typed_formula< int > w_
The width of the rectangle.
typed_formula< int > y_
The y coordinate of the rectangle.
rect_bounded_shape(const config &cfg)
Constructor.
typed_formula< int > h_
The height of the rectangle.
Definition of a rectangle.
rectangle_shape(const config &cfg)
Constructor.
Definition: canvas.cpp:84
int border_thickness_
Border thickness.
typed_formula< color_t > fill_color_
The border color of the rectangle.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:101
typed_formula< color_t > border_color_
The border color of the rectangle.
Definition of a rounded rectangle shape.
typed_formula< color_t > border_color_
The border color of the rounded rectangle.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:163
typed_formula< int > r_
The radius of the corners.
round_rectangle_shape(const config &cfg)
Constructor.
Definition: canvas.cpp:145
int border_thickness_
Border thickness.
typed_formula< color_t > fill_color_
The border color of the rounded rectangle.
font::pango_text::FONT_STYLE font_style_
The style of the text.
text_shape(const config &cfg)
Constructor.
Definition: canvas.cpp:398
typed_formula< bool > outline_
Whether to apply a text outline.
typed_formula< color_t > color_
The color of the text.
typed_formula< int > maximum_height_
The maximum height for the text.
typed_formula< bool > link_aware_
The link aware switch of the text.
typed_formula< PangoAlignment > text_alignment_
The alignment of the text.
typed_formula< color_t > highlight_color_
The color to be used for highlighting.
font::family_class font_family_
The text font family.
typed_formula< color_t > link_color_
The link color of the text.
typed_formula< int > maximum_width_
The maximum width for the text.
void draw(wfl::map_formula_callable &variables) override
Draws the canvas.
Definition: canvas.cpp:427
typed_formula< int > highlight_end_
typed_formula< int > highlight_start_
Start and end offsets for highlight.
typed_formula< unsigned > font_size_
The font size of the text.
unsigned characters_per_line_
The number of characters per line.
typed_formula< t_string > text_
The text to draw.
typed_formula< bool > text_markup_
The text markup switch of the text.
family_class
Font classes for get_font_families().
Generic file dialog.