The Battle for Wesnoth  1.19.5+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_font_size(int font_size)
112  {
113  font_size_ = font_size;
114  }
115 
116  void set_text_alpha(unsigned short alpha);
117 
118  const t_string& get_label() const
119  {
121  }
122 
123  // Show text marked up with help markup
124  void set_label(const t_string& text) override;
125 
126  // Show a help topic
127  void set_topic(const help::topic* topic);
128 
129  // Given a parsed config from help markup,
130  // layout it into a config that can be understood by canvas
131  std::pair<config, point> get_parsed_text(
132  const config& parsed_text,
133  const point& origin,
134  const unsigned init_width,
135  const bool finalize = false);
136 
137  // Attaches a callback function that will be called when a link is clicked
138  void register_link_callback(std::function<void(std::string)> link_handler);
139 
140 private:
141  /**
142  * Possible states of the widget.
143  *
144  * Note the order of the states must be the same as defined in settings.hpp.
145  */
146  enum state_t {
149  };
150 
151  void set_state(const state_t state);
152 
153  /**
154  * Current state of the widget.
155  *
156  * The state of the widget determines what to render and how the widget
157  * reacts to certain 'events'.
158  */
160 
161  /** Holds the rich_label can wrap or not. */
162  bool can_wrap_;
163 
164  /**
165  * The maximum number of characters per line.
166  *
167  * The maximum is not an exact maximum, it uses the average character width.
168  */
170 
171  /**
172  * Whether the rich_label is link aware, rendering links with special formatting
173  * and handling click events.
174  */
176 
177  /**
178  * What color links will be rendered in.
179  */
181 
182  /**
183  * Base font size
184  */
186 
188 
189  unsigned short text_alpha_;
190 
191  /** Inherited from styled_widget. */
192  virtual bool text_can_shrink() override
193  {
194  return can_shrink_;
195  }
196 
197  /** structure tree of the marked up text after parsing */
199 
200  /** The unparsed/raw text */
202 
203  /** Width and height of the canvas */
204  const unsigned init_w_;
206 
207  /** Padding */
208  unsigned padding_;
209 
210  /** Create template for text config that can be shown in canvas */
211  void default_text_config(config* txt_ptr, t_string text = "");
212 
213  std::pair<size_t, size_t> add_text(config& curr_item, std::string text);
214  void add_attribute(config& curr_item, std::string attr_name, size_t start = 0, size_t end = 0, std::string extra_data = "");
215  std::pair<size_t, size_t> add_text_with_attribute(config& curr_item, std::string text, std::string attr_name = "", std::string extra_data = "");
216 
217  void add_image(config& curr_item, std::string name, std::string align, bool has_prev_image, bool floating);
218  void add_link(config& curr_item, std::string name, std::string dest, const point& origin, int img_width);
219 
220  /** size calculation functions */
221  point get_text_size(config& text_cfg, unsigned width = 0) const;
222  point get_image_size(config& img_cfg) const;
223 
224  wfl::map_formula_callable setup_text_renderer(config text_cfg, unsigned width = 0) const;
225 
226  size_t get_split_location(std::string_view text, const point& pos);
227  std::vector<std::string> split_in_width(const std::string &s, const int font_size, const unsigned width);
228 
229  /** link variables and functions */
230  std::vector<std::pair<rect, std::string>> links_;
231 
232  std::function<void(std::string)> link_handler_;
233 
234  int get_offset_from_xy(const point& position) const
235  {
236  return font::get_text_renderer().xy_to_index(position);
237  }
238 
239  point get_xy_from_offset(const unsigned offset) const
240  {
242  }
243 
244  point calculate_best_size() const override
245  {
246  if(size_ == point{}) {
248  } else {
249  return size_;
250  }
251  }
252 
253 public:
254  /** Static type getter that does not rely on the widget being constructed. */
255  static const std::string& type();
256 
257 private:
258  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
259  virtual const std::string& get_control_type() const override;
260 
261  /* **** ***** ***** signal handlers ***** ****** **** */
262 
263  /**
264  * Left click signal handler: checks if we clicked on a hyperlink
265  */
266  void signal_handler_left_button_click(bool& handled);
267 
268  /**
269  * Mouse motion signal handler: checks if the cursor is on a hyperlink
270  */
271  void signal_handler_mouse_motion(bool& handled, const point& coordinate);
272 
273  /**
274  * Mouse leave signal handler: checks if the cursor left a hyperlink
275  */
276  void signal_handler_mouse_leave(bool& handled);
277 
278  /**
279  * Implementation detail for (re)setting the hyperlink cursor.
280  */
281  void update_mouse_cursor(bool enable);
282 };
283 
284 // }---------- DEFINITION ---------{
285 
287 {
288 
289  explicit rich_label_definition(const config& cfg);
290 
292  {
293  explicit resolution(const config& cfg);
294 
297  };
298 };
299 
300 // }---------- BUILDER -----------{
301 
302 namespace implementation
303 {
304 
306 {
307  builder_rich_label(const config& cfg);
308 
310 
311  virtual std::unique_ptr<widget> build() const override;
312 
313  PangoAlignment text_alignment;
316 };
317 
318 } // namespace implementation
319 
320 // }------------ END --------------
321 
322 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
int xy_to_index(const point &position) const
Definition: text.cpp:320
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:244
unsigned characters_per_line_
The maximum number of characters per line.
Definition: rich_label.hpp:169
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:858
void set_can_wrap(const bool wrap)
Definition: rich_label.hpp:92
state_t state_
Current state of the widget.
Definition: rich_label.hpp:159
void set_state(const state_t state)
Definition: rich_label.cpp:803
size_t get_split_location(std::string_view text, const point &pos)
Definition: rich_label.cpp:223
virtual bool get_active() const override
Gets the active state of the styled_widget.
Definition: rich_label.hpp:68
point get_text_size(config &text_cfg, unsigned width=0) const
size calculation functions
Definition: rich_label.cpp:92
bool can_wrap_
Holds the rich_label can wrap or not.
Definition: rich_label.hpp:162
virtual color_t get_link_color() const override
Returns the color string to be used with links.
Definition: rich_label.hpp:61
std::function< void(std::string)> link_handler_
Definition: rich_label.hpp:232
const t_string & get_label() const
Definition: rich_label.hpp:118
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:751
std::pair< size_t, size_t > add_text(config &curr_item, std::string text)
Definition: rich_label.cpp:111
void default_text_config(config *txt_ptr, t_string text="")
Create template for text config that can be shown in canvas.
Definition: rich_label.cpp:734
t_string unparsed_text_
The unparsed/raw text.
Definition: rich_label.hpp:201
void signal_handler_mouse_leave(bool &handled)
Mouse leave signal handler: checks if the cursor left a hyperlink.
Definition: rich_label.cpp:879
std::vector< std::pair< rect, std::string > > links_
link variables and functions
Definition: rich_label.hpp:230
void add_link(config &curr_item, std::string name, std::string dest, const point &origin, int img_width)
Definition: rich_label.cpp:177
int font_size_
Base font size.
Definition: rich_label.hpp:185
std::pair< size_t, size_t > add_text_with_attribute(config &curr_item, std::string text, std::string attr_name="", std::string extra_data="")
Definition: rich_label.cpp:128
point get_image_size(config &img_cfg) const
Definition: rich_label.cpp:100
std::vector< std::string > split_in_width(const std::string &s, const int font_size, const unsigned width)
Definition: rich_label.cpp:240
void add_attribute(config &curr_item, std::string attr_name, size_t start=0, size_t end=0, std::string extra_data="")
Definition: rich_label.cpp:119
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:189
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
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:239
std::pair< config, point > get_parsed_text(const config &parsed_text, const point &origin, const unsigned init_width, const bool finalize=false)
Definition: rich_label.cpp:267
virtual void set_active(const bool active) override
Sets the styled_widget's state.
Definition: rich_label.cpp:778
const unsigned init_w_
Width and height of the canvas.
Definition: rich_label.hpp:204
state_t
Possible states of the widget.
Definition: rich_label.hpp:146
void register_link_callback(std::function< void(std::string)> link_handler)
Definition: rich_label.cpp:811
void signal_handler_left_button_click(bool &handled)
Left click signal handler: checks if we clicked on a hyperlink.
Definition: rich_label.cpp:827
void set_font_size(int font_size)
Definition: rich_label.hpp:111
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
void set_topic(const help::topic *topic)
Definition: rich_label.cpp:255
int get_offset_from_xy(const point &position) const
Definition: rich_label.hpp:234
bool link_aware_
Whether the rich_label is link aware, rendering links with special formatting and handling click even...
Definition: rich_label.hpp:175
void add_image(config &curr_item, std::string name, std::string align, bool has_prev_image, bool floating)
Definition: rich_label.cpp:134
virtual unsigned get_characters_per_line() const override
Returns the number of characters per line.
Definition: rich_label.hpp:51
wfl::map_formula_callable setup_text_renderer(config text_cfg, unsigned width=0) const
Definition: rich_label.cpp:80
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:794
unsigned padding_
Padding.
Definition: rich_label.hpp:208
void set_link_aware(bool l)
Definition: rich_label.cpp:785
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:64
virtual bool text_can_shrink() override
Inherited from styled_widget.
Definition: rich_label.hpp:192
void set_text_alpha(unsigned short alpha)
Definition: rich_label.cpp:769
color_t link_color_
What color links will be rendered in.
Definition: rich_label.hpp:180
void set_label(const t_string &text) override
Definition: rich_label.cpp:260
void update_mouse_cursor(bool enable)
Implementation detail for (re)setting the hyperlink cursor.
Definition: rich_label.cpp:893
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:198
const t_string & get_label() const
const t_string & tooltip() const
virtual point calculate_best_size() const override
See widget::calculate_best_size.
bool empty() const
Definition: tstring.hpp:194
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
pango_text & get_text_renderer()
Returns a reference to a static pango_text object.
Definition: text.cpp:1136
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:939
virtual std::unique_ptr< widget > build() const=0
rich_label_definition(const config &cfg)
Definition: rich_label.cpp:908
A topic contains a title, an id and some text.
Definition: help_impl.hpp:115
Holds a 2D point.
Definition: point.hpp:25
static map_location::direction s