The Battle for Wesnoth  1.19.3+dev
rich_label.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2024
3  by Subhraman Sarkar (babaissarkar) <suvrax@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 #pragma once
17 
19 
20 #include "font/standard_colors.hpp"
23 #include "help/help_impl.hpp"
24 #include "serialization/parser.hpp"
25 
26 namespace gui2
27 {
28 namespace implementation
29 {
30  struct builder_rich_label;
31 }
32 
33 // ------------ WIDGET -----------{
34 
35 /**
36  *
37  * A rich_label takes marked up text and shows it correctly formatted and wrapped but no scrollbars are provided.
38  */
39 class rich_label : public styled_widget
40 {
42 
43 public:
44  explicit rich_label(const implementation::builder_rich_label& builder);
45 
46  virtual bool can_wrap() const override
47  {
48  return can_wrap_ || characters_per_line_ != 0;
49  }
50 
51  virtual unsigned get_characters_per_line() const override
52  {
53  return characters_per_line_;
54  }
55 
56  virtual bool get_link_aware() const override
57  {
58  return link_aware_;
59  }
60 
61  virtual color_t get_link_color() const override
62  {
63  return link_color_;
64  }
65 
66  virtual void set_active(const bool active) override;
67 
68  virtual bool get_active() const override
69  {
70  return state_ != DISABLED;
71  }
72 
73  virtual unsigned get_state() const override
74  {
75  return state_;
76  }
77 
78  bool disable_click_dismiss() const override
79  {
80  return false;
81  }
82 
83  virtual bool can_mouse_focus() const override
84  {
85  return !tooltip().empty() || get_link_aware();
86  }
87 
88  virtual void update_canvas() override;
89 
90  /* **** ***** ***** setters / getters for members ***** ****** **** */
91 
92  void set_can_wrap(const bool wrap)
93  {
94  can_wrap_ = wrap;
95  }
96 
97  void set_characters_per_line(const unsigned characters_per_line)
98  {
99  characters_per_line_ = characters_per_line;
100  }
101 
102  void set_link_aware(bool l);
103 
104  void set_link_color(const color_t& color);
105 
106  void set_can_shrink(bool can_shrink)
107  {
108  can_shrink_ = can_shrink;
109  }
110 
111  void set_width(unsigned width)
112  {
113  w_ = width;
114  }
115 
116  void set_text_alpha(unsigned short alpha);
117 
118  const t_string& get_label() const
119  {
121  }
122 
123  void set_label(const t_string& text) override;
124 
125  void register_link_callback(std::function<void(std::string)> link_handler)
126  {
127  link_handler_ = link_handler;
128  }
129 
130 private:
131  /**
132  * Possible states of the widget.
133  *
134  * Note the order of the states must be the same as defined in settings.hpp.
135  */
136  enum state_t {
139  };
140 
141  void set_state(const state_t state);
142 
143  /**
144  * Current state of the widget.
145  *
146  * The state of the widget determines what to render and how the widget
147  * reacts to certain 'events'.
148  */
150 
151  /** Holds the rich_label can wrap or not. */
152  bool can_wrap_;
153 
154  /**
155  * The maximum number of characters per line.
156  *
157  * The maximum is not an exact maximum, it uses the average character width.
158  */
160 
161  /**
162  * Whether the rich_label is link aware, rendering links with special formatting
163  * and handling click events.
164  */
166 
167  /**
168  * What color links will be rendered in.
169  */
171 
173 
174  unsigned short text_alpha_;
175 
176  /** Inherited from styled_widget. */
177  virtual bool text_can_shrink() override
178  {
179  return can_shrink_;
180  }
181 
182  /** structure tree of the marked up text after parsing */
184 
185  /** The unparsed/raw text */
187 
188  /** shapes used for size calculation */
189  std::unique_ptr<text_shape> tshape_;
190  std::unique_ptr<image_shape> ishape_;
191 
192  /** Width and height of the canvas */
193  unsigned w_, h_, x_;
194 
195  /** Padding */
196  unsigned padding_;
197 
198  /** Height of current text block */
199  unsigned txt_height_;
200 
201  /** Height of all previous blocks, combined */
203 
204  /** template for canvas text config */
205  void default_text_config(config* txt_ptr, t_string text = "");
206 
207  void add_text_with_attribute(config& curr_item, std::string text, std::string attr_name = "", std::string extra_data = "");
208  void add_text_with_attributes(config& curr_item, std::string text, std::vector<std::string> attr_names, std::vector<std::string> extra_data);
209  void add_image(config& curr_item, std::string name, std::string align, bool floating, point& img_size);
210  void add_link(config& curr_item, std::string name, std::string dest, int img_width);
211 
212  void append_if_not_empty(config_attribute_value* key, std::string suffix) {
213  if (!key->str().empty()) {
214  *key = key->str() + suffix;
215  }
216  }
217 
218  /** size calculation functions */
219  point get_text_size(config text_cfg, unsigned width = 0);
220  point get_image_size(config img_cfg);
221 
222  wfl::map_formula_callable setup_text_renderer(config text_cfg, unsigned width = 0);
223 
224  size_t get_split_location(std::string text, int img_height);
225 
226  /** link variables and functions */
227  std::vector<std::pair<rect, std::string>> links_;
228 
229  std::function<void(std::string)> link_handler_;
230 
231  point get_column_line(const point& position) const
232  {
233  return font::get_text_renderer().get_column_line(position);
234  }
235 
236  point get_xy_from_offset(const unsigned offset) const
237  {
239  }
240 
241  point calculate_best_size() const override
242  {
243  return point(w_, h_);
244  }
245 
246 public:
247  /** Static type getter that does not rely on the widget being constructed. */
248  static const std::string& type();
249 
250 private:
251  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
252  virtual const std::string& get_control_type() const override;
253 
254  /* **** ***** ***** signal handlers ***** ****** **** */
255 
256  /**
257  * Left click signal handler: checks if we clicked on a hyperlink
258  */
259  void signal_handler_left_button_click(bool& handled);
260 
261  /**
262  * Mouse motion signal handler: checks if the cursor is on a hyperlink
263  */
264  void signal_handler_mouse_motion(bool& handled, const point& coordinate);
265 
266  /**
267  * Mouse leave signal handler: checks if the cursor left a hyperlink
268  */
269  void signal_handler_mouse_leave(bool& handled);
270 
271  /**
272  * Implementation detail for (re)setting the hyperlink cursor.
273  */
274  void update_mouse_cursor(bool enable);
275 };
276 
277 // }---------- DEFINITION ---------{
278 
280 {
281 
282  explicit rich_label_definition(const config& cfg);
283 
285  {
286  explicit resolution(const config& cfg);
287 
289  };
290 };
291 
292 // }---------- BUILDER -----------{
293 
294 namespace implementation
295 {
296 
298 {
299  builder_rich_label(const config& cfg);
300 
302 
303  virtual std::unique_ptr<widget> build() const override;
304 
305  PangoAlignment text_alignment;
307  unsigned width;
308 };
309 
310 } // namespace implementation
311 
312 // }------------ END --------------
313 
314 } // namespace gui2
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
point get_column_line(const point &position) const
Gets the column of line of the character at the position.
Definition: text.cpp:286
point get_cursor_position(const unsigned column, const unsigned line=0) const
Gets the location for the cursor, in drawing coordinates.
Definition: text.cpp:185
A rich_label takes marked up text and shows it correctly formatted and wrapped but no scrollbars are ...
Definition: rich_label.hpp:40
point calculate_best_size() const override
See widget::calculate_best_size.
Definition: rich_label.hpp:241
unsigned characters_per_line_
The maximum number of characters per line.
Definition: rich_label.hpp:159
bool disable_click_dismiss() const override
Does the widget disable easy close?
Definition: rich_label.hpp:78
void signal_handler_mouse_motion(bool &handled, const point &coordinate)
Mouse motion signal handler: checks if the cursor is on a hyperlink.
Definition: rich_label.cpp:733
void set_can_wrap(const bool wrap)
Definition: rich_label.hpp:92
void append_if_not_empty(config_attribute_value *key, std::string suffix)
Definition: rich_label.hpp:212
state_t state_
Current state of the widget.
Definition: rich_label.hpp:149
void set_state(const state_t state)
Definition: rich_label.cpp:691
void add_text_with_attribute(config &curr_item, std::string text, std::string attr_name="", std::string extra_data="")
Definition: rich_label.cpp:101
size_t get_split_location(std::string text, int img_height)
Definition: rich_label.cpp:265
virtual bool get_active() const override
Gets the active state of the styled_widget.
Definition: rich_label.hpp:68
bool can_wrap_
Holds the rich_label can wrap or not.
Definition: rich_label.hpp:152
virtual color_t get_link_color() const override
Returns the color string to be used with links.
Definition: rich_label.hpp:61
void set_width(unsigned width)
Definition: rich_label.hpp:111
std::function< void(std::string)> link_handler_
Definition: rich_label.hpp:229
const t_string & get_label() const
Definition: rich_label.hpp:118
wfl::map_formula_callable setup_text_renderer(config text_cfg, unsigned width=0)
Definition: rich_label.cpp:74
virtual unsigned get_state() const override
Returns the id of the state.
Definition: rich_label.hpp:73
virtual void update_canvas() override
Updates the canvas(ses).
Definition: rich_label.cpp:640
unsigned w_
Width and height of the canvas.
Definition: rich_label.hpp:193
void add_link(config &curr_item, std::string name, std::string dest, int img_width)
Definition: rich_label.cpp:202
void default_text_config(config *txt_ptr, t_string text="")
template for canvas text config
Definition: rich_label.cpp:624
t_string unparsed_text_
The unparsed/raw text.
Definition: rich_label.hpp:186
void signal_handler_mouse_leave(bool &handled)
Mouse leave signal handler: checks if the cursor left a hyperlink.
Definition: rich_label.cpp:757
std::vector< std::pair< rect, std::string > > links_
link variables and functions
Definition: rich_label.hpp:227
std::unique_ptr< image_shape > ishape_
Definition: rich_label.hpp:190
virtual bool can_mouse_focus() const override
Whether the mouse move/click event go 'through' this widget.
Definition: rich_label.hpp:83
unsigned short text_alpha_
Definition: rich_label.hpp:174
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
point get_image_size(config img_cfg)
Definition: rich_label.cpp:92
void set_can_shrink(bool can_shrink)
Definition: rich_label.hpp:106
point get_xy_from_offset(const unsigned offset) const
Definition: rich_label.hpp:236
virtual void set_active(const bool active) override
Sets the styled_widget's state.
Definition: rich_label.cpp:666
void add_image(config &curr_item, std::string name, std::string align, bool floating, point &img_size)
Definition: rich_label.cpp:146
point get_text_size(config text_cfg, unsigned width=0)
size calculation functions
Definition: rich_label.cpp:87
point get_column_line(const point &position) const
Definition: rich_label.hpp:231
unsigned prev_blk_height_
Height of all previous blocks, combined.
Definition: rich_label.hpp:202
state_t
Possible states of the widget.
Definition: rich_label.hpp:136
void register_link_callback(std::function< void(std::string)> link_handler)
Definition: rich_label.hpp:125
void signal_handler_left_button_click(bool &handled)
Left click signal handler: checks if we clicked on a hyperlink.
Definition: rich_label.cpp:699
unsigned txt_height_
Height of current text block.
Definition: rich_label.hpp:199
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
bool link_aware_
Whether the rich_label is link aware, rendering links with special formatting and handling click even...
Definition: rich_label.hpp:165
virtual unsigned get_characters_per_line() const override
Returns the number of characters per line.
Definition: rich_label.hpp:51
virtual bool can_wrap() const override
Can the widget wrap.
Definition: rich_label.hpp:46
void set_link_color(const color_t &color)
Definition: rich_label.cpp:682
std::unique_ptr< text_shape > tshape_
shapes used for size calculation
Definition: rich_label.hpp:189
unsigned padding_
Padding.
Definition: rich_label.hpp:196
void set_link_aware(bool l)
Definition: rich_label.cpp:673
virtual bool get_link_aware() const override
Returns whether the label should be link_aware, in in rendering and in searching for links with get_l...
Definition: rich_label.hpp:56
rich_label(const implementation::builder_rich_label &builder)
Definition: rich_label.cpp:50
virtual bool text_can_shrink() override
Inherited from styled_widget.
Definition: rich_label.hpp:177
void add_text_with_attributes(config &curr_item, std::string text, std::vector< std::string > attr_names, std::vector< std::string > extra_data)
Definition: rich_label.cpp:123
void set_text_alpha(unsigned short alpha)
Definition: rich_label.cpp:657
color_t link_color_
What color links will be rendered in.
Definition: rich_label.hpp:170
void set_label(const t_string &text) override
Definition: rich_label.cpp:283
void update_mouse_cursor(bool enable)
Implementation detail for (re)setting the hyperlink cursor.
Definition: rich_label.cpp:771
void set_characters_per_line(const unsigned characters_per_line)
Definition: rich_label.hpp:97
config text_dom_
structure tree of the marked up text after parsing
Definition: rich_label.hpp:183
const t_string & get_label() const
const t_string & tooltip() const
bool empty() const
Definition: tstring.hpp:186
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:202
pango_text & get_text_renderer()
Returns a reference to a static pango_text object.
Definition: text.cpp:1118
Generic file dialog.
Contains the implementation details for lexical_cast and shouldn't be used directly.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
virtual std::unique_ptr< widget > build() const override
Definition: rich_label.cpp:816
virtual std::unique_ptr< widget > build() const=0
rich_label_definition(const config &cfg)
Definition: rich_label.cpp:786
Holds a 2D point.
Definition: point.hpp:25