The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
rich_label.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2024 - 2025
3 by Subhraman Sarkar (babaissarkar) <sbmskmm@protonmail.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
18#include "color.hpp"
20
23
24namespace gui2
25{
26namespace implementation
27{
28 struct builder_rich_label;
29}
30
31// ------------ WIDGET -----------{
32
33/**
34 *
35 * A rich_label takes marked up text and shows it correctly formatted and wrapped but no scrollbars are provided.
36 */
38{
40
41public:
42 explicit rich_label(const implementation::builder_rich_label& builder);
43
44 virtual bool can_wrap() const override
45 {
46 return can_wrap_ || characters_per_line_ != 0;
47 }
48
49 virtual unsigned get_characters_per_line() const override
50 {
52 }
53
54 virtual bool get_link_aware() const override
55 {
56 return link_aware_;
57 }
58
59 virtual color_t get_link_color() const override
60 {
61 return link_color_;
62 }
63
64 virtual void set_active(const bool) override;
65
66 virtual bool get_active() const override
67 {
68 return true; // Always enabled
69 }
70
71 virtual unsigned get_state() const override
72 {
73 return state_;
74 }
75
76 bool disable_click_dismiss() const override
77 {
78 return false;
79 }
80
81 virtual bool can_mouse_focus() const override
82 {
83 return !tooltip().empty() || get_link_aware();
84 }
85
86 virtual void request_reduce_height(const unsigned /*maximum_height*/) override {};
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_link_aware(bool l);
98
99 void set_link_color(const color_t& color);
100
101 void set_can_shrink(bool can_shrink)
102 {
103 can_shrink_ = can_shrink;
104 }
105
106 void set_font_family(const std::string& font_family)
107 {
108 font_family_ = font_family;
109 }
110
111 void set_font_size(int font_size)
112 {
113 font_size_ = font_size;
114 }
115
116 void set_font_style(const std::string& font_style)
117 {
118 font_style_ = font_style;
119 }
120
121 void set_text_alpha(unsigned short alpha);
122
123 // Show text marked up with help markup
124 void set_label(const t_string& text) override;
125
126 // Show a given DOM (given as a config)
127 void set_dom(const config& dom);
128
130 {
131 return init_w_;
132 }
133
134 // NOTE: set_label() must be done after this so the text can be
135 // laid out with the new width.
136 void set_width(const int width)
137 {
138 init_w_ = width;
139 }
140
141 typedef std::unique_ptr<canvas::shape> shape_ptr;
142
143 // Given a parsed config from help markup,
144 // layout it into a config that can be understood by canvas
145 std::pair<std::vector<shape_ptr>, point> get_parsed_text(
146 const config& parsed_text,
147 const point& origin,
148 const unsigned init_width,
149 const bool finalize = false);
150
151 // Attaches a callback function that will be called when a link is clicked
152 void register_link_callback(std::function<void(std::string)> link_handler);
153
154private:
155 /**
156 * Possible states of the widget.
157 *
158 * Note the order of the states must be the same as defined in settings.hpp.
159 */
160 enum state_t { ENABLED }; // Always enabled
161
162 void set_state(const state_t state);
163
164 /**
165 * Current state of the widget.
166 *
167 * The state of the widget determines what to render and how the widget
168 * reacts to certain 'events'.
169 */
171
172 /** Holds the rich_label can wrap or not. */
174
175 /**
176 * The maximum number of characters per line.
177 *
178 * The maximum is not an exact maximum, it uses the average character width.
179 */
181
182 /**
183 * Whether the rich_label is link aware, rendering links with special formatting
184 * and handling click events.
185 */
187
188 /**
189 * Base text color, enabled state
190 */
192
193 /**
194 * Base text color, disabled state
195 */
197
198 /**
199 * What color links will be rendered in.
200 */
202
203 /**
204 * Color variables that can be used in place of colors strings, like `<row bgcolor=color1>`
205 */
206 std::map<std::string, color_t> predef_colors_;
207
208 /**
209 * Base font family
210 */
211 std::string font_family_;
212
213 /**
214 * Base font size
215 */
217
218 /**
219 * Base font style
220 */
221 std::string font_style_;
222
224
225 unsigned short text_alpha_;
226
227 /** Inherited from styled_widget. */
228 virtual bool text_can_shrink() override
229 {
230 return can_shrink_;
231 }
232
233 /** Width and height of the canvas */
234 unsigned init_w_;
236
238
239 /** Padding */
241
242 /** If color is a predefined color set in resolution, return it, otherwise decode using `font::string_to_color`. */
243 color_t get_color(const std::string& color);
244
245 /** Create template for text config that can be shown in canvas */
246 std::unique_ptr<gui2::text_shape> new_text_shape(const point& origin, const int max_width);
247
248 std::pair<std::size_t, std::size_t> add_text_with_attribute(
249 text_shape& tshape,
250 const t_string& text,
251 const std::string& attr_name = "",
252 const std::string& extra_data = "");
253
254 void add_link(
255 text_shape& tshape,
256 const std::string& name,
257 const std::string& dest,
258 const point& origin,
259 int img_width);
260
261 /** size calculation functions */
262 wfl::map_formula_callable setup_text_renderer(text_shape& tshape, unsigned width) const;
263 point get_text_size(text_shape& tshape, unsigned width) const;
264 point get_image_size(const std::string& path) const;
265
266 std::size_t get_split_location(std::string_view text, const point& pos);
267
268 /** link variables and functions */
269 std::vector<std::pair<rect, std::string>> links_;
270
271 std::function<void(std::string)> link_handler_;
272
273 int get_offset_from_xy(const point& position) const
274 {
275 return std::get<0>(font::get_text_renderer().xy_to_index(position));
276 }
277
278 point get_xy_from_offset(const unsigned offset) const
279 {
281 }
282
283 point calculate_best_size() const override;
284
285 void request_reduce_width(const unsigned maximum_width) override;
286
287 void place(const point& origin, const point& size) override;
288
289public:
290 /** Static type getter that does not rely on the widget being constructed. */
291 static const std::string& type();
292
293private:
294 /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
295 virtual const std::string& get_control_type() const override;
296
297 /* **** ***** ***** signal handlers ***** ****** **** */
298
299 /**
300 * Left click signal handler: checks if we clicked on a hyperlink
301 */
302 void signal_handler_left_button_click(bool& handled);
303
304 /**
305 * Mouse motion signal handler: checks if the cursor is on a hyperlink
306 */
307 void signal_handler_mouse_motion(bool& handled, const point& coordinate);
308
309 /**
310 * Mouse leave signal handler: checks if the cursor left a hyperlink
311 */
312 void signal_handler_mouse_leave(bool& handled);
313
314 /**
315 * Implementation detail for (re)setting the hyperlink cursor.
316 */
317 void update_mouse_cursor(bool enable);
318};
319
320// }---------- DEFINITION ---------{
321
323{
324
325 explicit rich_label_definition(const config& cfg);
326
328 {
329 explicit resolution(const config& cfg);
330
333 std::string font_family;
335 std::string font_style;
336 std::map<std::string, color_t> colors;
337 };
338};
339
340// }---------- BUILDER -----------{
341
342namespace implementation
343{
344
346{
348
350
351 virtual std::unique_ptr<widget> build() const override;
352
353 PangoAlignment text_alignment;
355 unsigned padding;
356};
357
358} // namespace implementation
359
360// }------------ END --------------
361
362} // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
point get_cursor_position(const unsigned offset, const unsigned line=0) const
Gets the location for the cursor, in drawing coordinates.
Definition text.cpp:225
A rich_label takes marked up text and shows it correctly formatted and wrapped but no scrollbars are ...
point calculate_best_size() const override
See widget::calculate_best_size.
unsigned characters_per_line_
The maximum number of characters per line.
bool disable_click_dismiss() const override
Does the widget disable easy close?
void signal_handler_mouse_motion(bool &handled, const point &coordinate)
Mouse motion signal handler: checks if the cursor is on a hyperlink.
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
void set_can_wrap(const bool wrap)
state_t state_
Current state of the widget.
virtual void set_active(const bool) override
Sets the styled_widget's state.
void set_state(const state_t state)
color_t text_color_enabled_
Base text color, enabled state.
virtual bool get_active() const override
Gets the active state of the styled_widget.
bool can_wrap_
Holds the rich_label can wrap or not.
virtual color_t get_link_color() const override
Returns the color string to be used with links.
std::unique_ptr< canvas::shape > shape_ptr
std::function< void(std::string)> link_handler_
virtual unsigned get_state() const override
Returns the id of the state.
virtual void update_canvas() override
Updates the canvas(ses).
std::pair< std::vector< shape_ptr >, point > get_parsed_text(const config &parsed_text, const point &origin, const unsigned init_width, const bool finalize=false)
int padding_
Padding.
void signal_handler_mouse_leave(bool &handled)
Mouse leave signal handler: checks if the cursor left a hyperlink.
std::vector< std::pair< rect, std::string > > links_
link variables and functions
void place(const point &origin, const point &size) override
See widget::place.
int font_size_
Base font size.
virtual bool can_mouse_focus() const override
Whether the mouse move/click event go 'through' this widget.
void set_width(const int width)
unsigned short text_alpha_
std::unique_ptr< gui2::text_shape > new_text_shape(const point &origin, const int max_width)
Create template for text config that can be shown in canvas.
std::string font_family_
Base font family.
unsigned init_w_
Width and height of the canvas.
void set_font_style(const std::string &font_style)
void set_dom(const config &dom)
void set_can_shrink(bool can_shrink)
point get_xy_from_offset(const unsigned offset) const
color_t get_color(const std::string &color)
If color is a predefined color set in resolution, return it, otherwise decode using font::string_to_c...
wfl::map_formula_callable setup_text_renderer(text_shape &tshape, unsigned width) const
size calculation functions
void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
std::string font_style_
Base font style.
state_t
Possible states of the widget.
void register_link_callback(std::function< void(std::string)> link_handler)
virtual void request_reduce_height(const unsigned) override
See widget::request_reduce_height.
void signal_handler_left_button_click(bool &handled)
Left click signal handler: checks if we clicked on a hyperlink.
void set_font_size(int font_size)
int get_offset_from_xy(const point &position) const
point get_image_size(const std::string &path) const
bool link_aware_
Whether the rich_label is link aware, rendering links with special formatting and handling click even...
virtual unsigned get_characters_per_line() const override
Returns the number of characters per line.
virtual bool can_wrap() const override
Can the widget wrap.
void set_link_color(const color_t &color)
std::map< std::string, color_t > predef_colors_
Color variables that can be used in place of colors strings, like <row bgcolor=color1>
void set_link_aware(bool l)
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...
void add_link(text_shape &tshape, const std::string &name, const std::string &dest, const point &origin, int img_width)
void set_font_family(const std::string &font_family)
virtual bool text_can_shrink() override
Inherited from styled_widget.
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
void set_text_alpha(unsigned short alpha)
color_t link_color_
What color links will be rendered in.
void set_label(const t_string &text) override
point get_text_size(text_shape &tshape, unsigned width) const
void update_mouse_cursor(bool enable)
Implementation detail for (re)setting the hyperlink cursor.
color_t text_color_disabled_
Base text color, disabled state.
std::pair< std::size_t, std::size_t > add_text_with_attribute(text_shape &tshape, const t_string &text, const std::string &attr_name="", const std::string &extra_data="")
std::size_t get_split_location(std::string_view text, const point &pos)
const t_string & tooltip() const
bool empty() const
Definition tstring.hpp:200
const config * cfg
pango_text & get_text_renderer()
Returns a reference to a static pango_text object.
Definition text.cpp:952
Generic file dialog.
Contains the implementation details for lexical_cast and shouldn't be used directly.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition color.hpp:51
virtual std::unique_ptr< widget > build() const override
virtual std::unique_ptr< widget > build() const=0
std::map< std::string, color_t > colors
Holds a 2D point.
Definition point.hpp:25