The Battle for Wesnoth  1.19.5+dev
styled_widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 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 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
20 #include "formatter.hpp"
21 #include "formula/string_utils.hpp"
22 #include "gettext.hpp"
26 #include "gui/core/log.hpp"
27 #include "gui/dialogs/tooltip.hpp"
28 #include "gui/widgets/settings.hpp"
29 #include "hotkey/hotkey_item.hpp"
30 #include "sdl/rect.hpp"
31 #include "wml_exception.hpp"
32 #include <functional>
33 
34 #include <algorithm>
35 #include <iomanip>
36 
37 #define LOG_SCOPE_HEADER \
38  "styled_widget(" + get_control_type() + ") [" + id() + "] " + __func__
39 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
40 
41 namespace gui2
42 {
43 
44 // ------------ WIDGET -----------{
45 
47  const std::string& control_type)
48  : widget(builder)
49  , definition_(builder.definition)
50  , label_(builder.label_string)
51  , use_markup_(builder.use_markup)
52  , use_tooltip_on_label_overflow_(builder.use_tooltip_on_label_overflow)
53  , tooltip_(builder.tooltip)
54  , help_message_(builder.help)
55  , config_(get_control(control_type, definition_))
56  , canvases_(config_->state.size()) // One canvas per state
57  , renderer_()
58  , text_maximum_width_(0)
59  , text_alignment_(PANGO_ALIGN_LEFT)
60  , text_ellipse_mode_(PANGO_ELLIPSIZE_END)
61  , shrunken_(false)
62 {
63  /*
64  * Fill in each canvas from the widget state definitons.
65  *
66  * Most widgets have a single canvas. However, some widgets such as toggle_panel
67  * and toggle_button have a variable canvas count determined by their definitions.
68  */
69  for(unsigned i = 0; i < config_->state.size(); ++i) {
70  canvases_[i].set_cfg(config_->state[i].canvas_cfg_);
71  }
72 
73  // Initialize all the canvas variables.
74  update_canvas();
75 
76  // Enable hover behavior if a tooltip was provided.
78 
79  connect_signal<event::SHOW_TOOLTIP>(std::bind(
80  &styled_widget::signal_handler_show_tooltip, this, std::placeholders::_2, std::placeholders::_3, std::placeholders::_5));
81 
82  connect_signal<event::SHOW_HELPTIP>(std::bind(
83  &styled_widget::signal_handler_show_helptip, this, std::placeholders::_2, std::placeholders::_3, std::placeholders::_5));
84 
85  connect_signal<event::NOTIFY_REMOVE_TOOLTIP>(std::bind(
86  &styled_widget::signal_handler_notify_remove_tooltip, this, std::placeholders::_2, std::placeholders::_3));
87 }
88 
90 {
91  /** @todo document this feature on the wiki. */
92  /** @todo do we need to add the debug colors here as well? */
93  widget_item::const_iterator itor = data.find("id");
94  if(itor != data.end()) {
95  set_id(itor->second);
96  }
97 
98  itor = data.find("linked_group");
99  if(itor != data.end()) {
100  set_linked_group(itor->second);
101  }
102 
103  itor = data.find("label");
104  if(itor != data.end()) {
105  set_label(itor->second);
106  }
107 
108  itor = data.find("tooltip");
109  if(itor != data.end()) {
110  set_tooltip(itor->second);
111  }
112 
113  itor = data.find("help");
114  if(itor != data.end()) {
115  set_help_message(itor->second);
116  }
117 
118  itor = data.find("use_markup");
119  if(itor != data.end()) {
120  set_use_markup(utils::string_bool(itor->second));
121  }
122 
123  itor = data.find("text_alignment");
124  if(itor != data.end()) {
126  }
127 }
128 
130 {
132 }
133 
135 {
136  return std::make_unique<iteration::walker::widget>(*this);
137 }
138 
140 {
141  assert(config_);
142 
143  point result(config_->min_width, config_->min_height);
144 
145  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
146  return result;
147 }
148 
150 {
151  assert(config_);
152 
153  point result(config_->default_width, config_->default_height);
154 
155  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
156  return result;
157 }
158 
160 {
161  assert(config_);
162 
163  point result(config_->max_width, config_->max_height);
164 
165  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
166  return result;
167 }
168 
170 {
171  return 0;
172 }
173 
175 {
176  return false;
177 }
178 
180 {
181  return color_t::from_hex_string("ffff00");
182 }
183 
184 void styled_widget::layout_initialize(const bool full_initialization)
185 {
186  // Inherited.
187  widget::layout_initialize(full_initialization);
188 
189  if(full_initialization) {
190  shrunken_ = false;
191  }
192 }
193 
194 void styled_widget::request_reduce_width(const unsigned maximum_width)
195 {
196  assert(config_);
197 
198  if(!label_.empty() && can_wrap()) {
199 
201  point(), point(maximum_width - config_->text_extra_width, 0));
202 
203  size.x += config_->text_extra_width;
204  size.y += config_->text_extra_height;
205 
207 
208  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
209  << "' maximum_width " << maximum_width << " result " << size
210  << ".";
211 
212  } else if(label_.empty() || text_can_shrink()) {
215  size.x = std::min(size.x, std::max<int>(maximum_width, min_size.x));
217 
218  DBG_GUI_L << LOG_HEADER << " styled_widget " << id()
219  << " maximum_width " << maximum_width << " result " << size
220  << ".";
221  } else {
222  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
223  << "' failed; either no label or wrapping not allowed.";
224  }
225 }
226 
227 void styled_widget::request_reduce_height(const unsigned maximum_height)
228 {
229  if(!label_.empty()) {
230  // Do nothing
231  } else {
234  size.y = std::min(size.y, std::max<int>(maximum_height, min_size.y));
236 
237  DBG_GUI_L << LOG_HEADER << " styled_widget " << id()
238  << " maximum_height " << maximum_height << " result " << size
239  << ".";
240  }
241 }
242 
244 {
245  assert(config_);
246  if(label_.empty()) {
247  DBG_GUI_L << LOG_HEADER << " empty label return default.";
248  return get_config_default_size();
249  }
250 
251  const point minimum = get_config_default_size();
252  const point maximum = get_config_maximum_size();
253 
254  /**
255  * @todo The value send should subtract the border size
256  * and read it after calculation to get the proper result.
257  */
258  point result = get_best_text_size(minimum, maximum);
259  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
260  << "' result " << result << ".";
261  return result;
262 }
263 
264 void styled_widget::place(const point& origin, const point& size)
265 {
266  // resize canvasses
267  for(auto & canvas : canvases_)
268  {
270  }
271 
272  // Note we assume that the best size has been queried but otherwise it
273  // should return false.
275  && tooltip_.empty()) {
276 
278  }
279 
280  // inherited
281  widget::place(origin, size);
282 
283  // update the state of the canvas after the sizes have been set.
284  update_canvas();
285 }
286 
287 widget* styled_widget::find_at(const point& coordinate, const bool must_be_active)
288 {
289  return (widget::find_at(coordinate, must_be_active)
290  && (!must_be_active || get_active()))
291  ? this
292  : nullptr;
293 }
294 
296  const bool must_be_active) const
297 {
298  return (widget::find_at(coordinate, must_be_active)
299  && (!must_be_active || get_active()))
300  ? this
301  : nullptr;
302 }
303 
304 widget* styled_widget::find(const std::string& id, const bool must_be_active)
305 {
306  return (widget::find(id, must_be_active)
307  && (!must_be_active || get_active()))
308  ? this
309  : nullptr;
310 }
311 
312 const widget* styled_widget::find(const std::string& id, const bool must_be_active)
313  const
314 {
315  return (widget::find(id, must_be_active)
316  && (!must_be_active || get_active()))
317  ? this
318  : nullptr;
319 }
320 
322 {
323  if(label == label_) {
324  return;
325  }
326 
327  label_ = label;
329  update_canvas();
330  queue_redraw();
331 
332  // FIXME: This isn't the most elegant solution. Typically, we don't rely on the text rendering
333  // cache for anything except size calculations, but since we have link awareness now we need to
334  // update its text else `get_label_link` will return old results. I'm not actually sure why the
335  // results seem to only remain one invocation of `set_label` behind the current text, but that
336  // is what testing revealed (see https://github.com/wesnoth/wesnoth/pull/5363).
337  //
338  // -- vultraz, 2020-12-17
340 }
341 
342 void styled_widget::set_use_markup(bool use_markup)
343 {
344  if(use_markup == use_markup_) {
345  return;
346  }
347 
348  use_markup_ = use_markup;
349  update_canvas();
350  queue_redraw();
351 }
352 
353 void styled_widget::set_text_alignment(const PangoAlignment text_alignment)
354 {
355  if(text_alignment_ == text_alignment) {
356  return;
357  }
358 
359  text_alignment_ = text_alignment;
360  update_canvas();
361  queue_redraw();
362 }
363 
364 void styled_widget::set_text_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
365 {
366  if(text_ellipse_mode_ == ellipse_mode) {
367  return;
368  }
369 
370  text_ellipse_mode_ = ellipse_mode;
371  update_canvas();
372  queue_redraw();
373 }
374 
376 {
377  const int max_width = get_text_maximum_width();
378  const int max_height = get_text_maximum_height();
379 
380  // set label in canvases
381  for(auto & canvas : canvases_)
382  {
384  canvas.set_variable("text_markup", wfl::variant(use_markup_));
385  canvas.set_variable("text_link_aware", wfl::variant(get_link_aware()));
386 
387  // Possible TODO: consider making a formula_callable for colors.
388  color_t link_color = get_link_color();
389  std::vector<wfl::variant> link_color_as_list {
390  wfl::variant(link_color.r),
391  wfl::variant(link_color.g),
392  wfl::variant(link_color.b),
393  wfl::variant(link_color.a)
394  };
395 
396  canvas.set_variable("text_link_color", wfl::variant(link_color_as_list));
397  canvas.set_variable("text_alignment",
399  canvas.set_variable("text_maximum_width", wfl::variant(max_width));
400  canvas.set_variable("text_maximum_height", wfl::variant(max_height));
402  canvas.set_variable("text_characters_per_line",
404  }
405 }
406 
408 {
409  if (cached_text_font_size_ == 0) {
410  assert(config_);
411 
413  }
414  return cached_text_font_size_;
415 }
416 
418 {
419  assert(config_);
420 
422  : get_width() - config_->text_extra_width;
423 }
424 
426 {
427  assert(config_);
428 
429  return get_height() - config_->text_extra_height;
430 }
431 
433 {
434  DBG_GUI_D << LOG_HEADER << " label '" << debug_truncate(label_.str()) << "' size "
435  << get_rectangle() << ".";
436 
437  if(!get_canvas(get_state()).update_blur(get_rectangle())) {
438  return false;
439  }
441  return true;
442 }
443 
445 {
446  /* DO NOTHING */
447  return true;
448 }
449 
450 point styled_widget::get_best_text_size(point minimum_size, point maximum_size) const
451 {
453 
454  assert(!label_.empty());
455 
456  // Try with the minimum wanted size.
457  const int maximum_width = text_maximum_width_ != 0
459  : maximum_size.x;
460 
461  /*
462  * NOTE: text rendering does *not* happen here. That happens in the text_shape
463  * canvas class. Instead, this just leverages the pango text rendering engine to
464  * calculate the area this widget will need to successfully render its text later.
465  */
466  renderer_
469  .set_family_class(config_->text_font_family)
471  .set_font_style(config_->text_font_style)
473  .set_maximum_width(maximum_width)
477 
478  if(get_characters_per_line() != 0 && !can_wrap()) {
480  << " Limited the number of characters per line, "
481  << "but wrapping is not set, output may not be as expected.";
482  }
483 
484  DBG_GUI_L << LOG_HEADER << "\n"
485  << std::boolalpha
486  << "Label: '" << debug_truncate(label_.str()) << "'\n\n"
487  << "Status:\n"
488  << "minimum_size: " << minimum_size << "\n"
489  << "maximum_size: " << maximum_size << "\n"
490  << "maximum width of text: " << text_maximum_width_ << "\n"
491  << "can_wrap: " << can_wrap() << "\n"
492  << "characters_per_line: " << get_characters_per_line() << "\n"
493  << "truncated: " << renderer_.is_truncated() << "\n"
494  << "renderer size: " << renderer_.get_size() << "\n"
495  << std::noboolalpha;
496 
497  const point border(config_->text_extra_width,
498  config_->text_extra_height);
499 
500  // If doesn't fit try the maximum.
501  if(renderer_.is_truncated() && !can_wrap()) {
502  // FIXME if maximum size is defined we should look at that
503  // but also we don't adjust for the extra text space yet!!!
504  maximum_size = point(config_->max_width,
505  config_->max_height);
506 
507  renderer_.set_maximum_width(maximum_size.x ? maximum_size.x - border.x : -1);
508  }
509 
510  // Get the resulting size.
512 
513  if(size.x < minimum_size.x) {
514  size.x = minimum_size.x;
515  }
516 
517  if(size.y < minimum_size.y) {
518  size.y = minimum_size.y;
519  }
520 
521  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
522  << "' result " << size << ".";
523  return size;
524 }
525 
527  bool& handled,
528  const point& location)
529 {
530  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
531 
532  if(!tooltip_.empty()) {
533  std::string tip = tooltip_;
534  if(!help_message_.empty()) {
535  utils::string_map symbols;
536  symbols["hotkey"] = hotkey::get_names(
539 
542  }
543 
545  handled = fire(event::MESSAGE_SHOW_TOOLTIP, *this, message);
546  }
547 }
548 
550  bool& handled,
551  const point& location)
552 {
553  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
554 
555  if(!help_message_.empty()) {
557  handled = fire(event::MESSAGE_SHOW_HELPTIP, *this, message);
558  }
559 }
560 
562  bool& handled)
563 {
564  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
565 
566  /*
567  * This makes the class know the tip code rather intimately. An
568  * alternative is to add a message to the window to remove the tip.
569  * Might be done later.
570  */
572 
573  handled = true;
574 }
575 
576 std::string styled_widget::get_label_token(const point & position, const char * delim) const
577 {
578  return renderer_.get_token(position, delim);
579 }
580 
581 std::string styled_widget::get_label_link(const point & position) const
582 {
583  return renderer_.get_link(position);
584 }
585 
586 // }---------- BUILDER -----------{
587 
588 namespace implementation
589 {
590 
592  : builder_widget(cfg)
593  , definition(cfg["definition"])
594  , label_string(cfg["label"].t_str())
595  , tooltip(cfg["tooltip"].t_str())
596  , help(cfg["help"].t_str())
597  , use_tooltip_on_label_overflow(true)
598  , use_markup(cfg["use_markup"].to_bool(false))
599 {
600  if(definition.empty()) {
601  definition = "default";
602  }
603 
605  help.empty() || !tooltip.empty(),
606  _("Found a widget with a helptip and without a tooltip."),
607  formatter() << "id '" << id << "' label '" << label_string
608  << "' helptip '" << help << "'.");
609 
610 
611  DBG_GUI_P << "Window builder: found styled_widget with id '" << id
612  << "' and definition '" << definition << "'.";
613 }
614 
615 std::unique_ptr<widget> builder_styled_widget::build(const replacements_map& /*replacements*/) const
616 {
617  return build();
618 }
619 
620 } // namespace implementation
621 
622 // }------------ END --------------
623 
624 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
pango_text & set_font_style(const FONT_STYLE font_style)
Definition: text.cpp:544
point get_size()
Returns the size of the text, in drawing coordinates.
Definition: text.cpp:150
pango_text & set_characters_per_line(const unsigned characters_per_line)
Definition: text.cpp:579
pango_text & set_family_class(font::family_class fclass)
Definition: text.cpp:522
pango_text & set_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
Definition: text.cpp:615
pango_text & set_alignment(const PangoAlignment alignment)
Definition: text.cpp:635
pango_text & set_font_size(unsigned font_size)
Definition: text.cpp:532
pango_text & set_link_aware(bool b)
Definition: text.cpp:658
std::string get_token(const point &position, const char *delimiters=" \n\r\t") const
Gets the largest collection of characters, including the token at position, and not including any cha...
Definition: text.cpp:239
bool set_text(const std::string &text, const bool markedup)
Sets the text to render.
Definition: text.cpp:484
bool is_truncated() const
Has the text been truncated? This happens if it exceeds max width or height.
Definition: text.cpp:158
pango_text & set_maximum_width(int width)
Definition: text.cpp:563
pango_text & set_link_color(const color_t &color)
Definition: text.cpp:667
std::string get_link(const point &position) const
Checks if position points to a character in a link in the text, returns it if so, empty string otherw...
Definition: text.cpp:271
std::ostringstream wrapper.
Definition: formatter.hpp:40
A simple canvas which can be drawn upon.
Definition: canvas.hpp:45
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:154
void draw()
Draw the canvas' shapes onto the screen.
Definition: canvas.cpp:634
void set_size(const point &size)
Definition: canvas.cpp:709
Main class to show messages to the user.
Definition: message.hpp:36
At the moment two kinds of tips are known:
Definition: tooltip.cpp:41
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:74
void set_wants_mouse_hover(const bool hover=true)
t_string help_message_
Tooltip text.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
int text_maximum_width_
The maximum width for the text in a styled_widget.
void set_tooltip(const t_string &tooltip)
bool use_markup_
Use markup for the label?
PangoEllipsizeMode text_ellipse_mode_
The ellipsize mode of the text in a styled_widget.
font::pango_text renderer_
Text renderer object used for size calculations.
virtual unsigned get_state() const =0
Returns the id of the state.
point get_config_maximum_size() const
Gets the best size as defined in the config.
t_string tooltip_
Tooltip text.
bool use_tooltip_on_label_overflow_
If the text doesn't fit on the label should the text be used as tooltip?
int get_text_maximum_width() const
Returns the maximum width available for the text.
virtual unsigned get_characters_per_line() const
Returns the number of characters per line.
point get_config_minimum_size() const
Gets the minimum size as defined in the config.
std::string get_label_link(const point &position) const
int get_text_maximum_height() const
Returns the maximum height available for the text.
void signal_handler_show_helptip(const event::ui_event event, bool &handled, const point &location)
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
virtual void update_canvas()
Updates the canvas(ses).
virtual bool get_link_aware() const
Returns whether the label should be link_aware, in in rendering and in searching for links with get_l...
void set_help_message(const t_string &help_message)
point get_config_default_size() const
Gets the default size as defined in the config.
std::vector< canvas > canvases_
Holds all canvas objects for a styled_widget.
PangoEllipsizeMode get_text_ellipse_mode() const
Get the text's ellipsize mode.
virtual color_t get_link_color() const
Returns the color string to be used with links.
void signal_handler_notify_remove_tooltip(const event::ui_event event, bool &handled)
bool shrunken_
Is the widget smaller as it's best size?
PangoAlignment text_alignment_
The alignment of the text in a styled_widget.
virtual void set_members(const widget_item &data)
Sets the members of the styled_widget.
virtual bool impl_draw_background() override
See widget::impl_draw_background.
point get_best_text_size(point minimum_size, point maximum_size={0, 0}) const
Gets the best size for a text.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual void set_text_alignment(const PangoAlignment text_alignment)
virtual bool get_active() const =0
Gets the active state of the styled_widget.
resolution_definition_ptr config_
Contains the pointer to the configuration.
virtual iteration::walker_ptr create_walker() override
See widget::create_walker.
virtual bool impl_draw_foreground() override
See widget::impl_draw_foreground.
std::string get_label_token(const point &position, const char *delimiters=" \n\r\t") const
Exposes font::pango_text::get_token, for the text label of this styled_widget.
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
virtual void set_label(const t_string &text)
virtual bool text_can_shrink()
Gets whether a widget can shrink past its optimal size even if it's text-based (such as labels);.
void set_text_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
canvas & get_canvas(const unsigned index)
void signal_handler_show_tooltip(const event::ui_event event, bool &handled, const point &location)
styled_widget(const implementation::builder_styled_widget &builder, const std::string &control_type)
Constructor.
virtual void set_use_markup(bool use_markup)
t_string label_
Contain the non-editable text associated with styled_widget.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
unsigned int get_text_font_size() const
Resolves and returns the text_font_size.
unsigned int cached_text_font_size_
Contains the evaluated text_font_size from the configuration.
Base class for all widgets.
Definition: widget.hpp:55
void set_layout_size(const point &size)
Definition: widget.cpp:346
point get_best_size() const
Gets the best size for the widget.
Definition: widget.cpp:203
virtual void place(const point &origin, const point &size)
Places the widget.
Definition: widget.cpp:248
void set_id(const std::string &id)
Definition: widget.cpp:98
virtual void layout_initialize(const bool full_initialization)
How the layout engine works.
Definition: widget.cpp:177
void set_linked_group(const std::string &linked_group)
Definition: widget.cpp:356
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:464
visibility get_visible() const
Definition: widget.cpp:506
virtual widget * find(const std::string &id, const bool must_be_active)
Returns a widget with the wanted id.
Definition: widget.cpp:560
unsigned get_width() const
Definition: widget.cpp:336
unsigned get_height() const
Definition: widget.cpp:341
const std::string & id() const
Definition: widget.cpp:110
@ visible
The user sets the widget visible, that means:
rect get_rectangle() const
Gets the bounding rectangle of the widget on the screen.
Definition: widget.cpp:321
virtual widget * find_at(const point &coordinate, const bool must_be_active)
Returns the widget at the wanted coordinates.
Definition: widget.cpp:549
virtual bool can_wrap() const
Can the widget wrap.
Definition: widget.cpp:225
bool empty() const
Definition: tstring.hpp:194
const std::string & str() const
Definition: tstring.hpp:198
This file contains the definitions for the gui2::event::message class.
@ border
The border of the map.
std::size_t i
Definition: function.cpp:1028
static std::string _(const char *str)
Definition: gettext.hpp:93
Define the common log macros for the gui toolkit.
#define DBG_GUI_L
Definition: log.hpp:55
#define DBG_GUI_P
Definition: log.hpp:66
#define WRN_GUI_L
Definition: log.hpp:57
#define DBG_GUI_E
Definition: log.hpp:35
#define DBG_GUI_D
Definition: log.hpp:29
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp:200
#define log_scope2(domain, description)
Definition: log.hpp:279
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:202
void remove()
Removes a tip.
Definition: tooltip.cpp:94
static std::unique_ptr< tooltip > tip
Definition: tooltip.cpp:62
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
@ MESSAGE_SHOW_TOOLTIP
Definition: handler.hpp:164
@ MESSAGE_SHOW_HELPTIP
Definition: handler.hpp:165
std::unique_ptr< class walker_base > walker_ptr
Definition: widget.hpp:44
t_string has_helptip_message
Definition: settings.cpp:53
Generic file dialog.
void get_screen_size_variables(wfl::map_formula_callable &variable)
Gets a formula object with the screen size.
Definition: helper.cpp:125
std::string_view debug_truncate(std::string_view text)
Returns a truncated version of the text.
Definition: helper.cpp:148
std::map< std::string, t_string > widget_item
Definition: widget.hpp:33
PangoAlignment decode_text_alignment(const std::string &alignment)
Converts a text alignment string to a text alignment.
Definition: helper.cpp:89
lg::log_domain log_gui_layout("gui/layout")
Definition: log.hpp:54
resolution_definition_ptr get_control(const std::string &control_type, const std::string &definition)
Returns the appropriate config data for a widget instance fom the active GUI definition.
std::string encode_text_alignment(const PangoAlignment alignment)
Converts a text alignment to its string representation.
Definition: helper.cpp:104
std::string get_names(const std::string &id)
Returns a comma-separated string of hotkey names.
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.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
bool string_bool(const std::string &str, bool def)
Convert no, false, off, 0, 0.0 to false, empty to def, and others to true.
std::map< std::string, t_string > string_map
std::string_view data
Definition: picture.cpp:178
Contains the SDL_Rect helper code.
This file contains the settings handling of the widget library.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
static color_t from_hex_string(std::string_view c)
Creates a new color_t object from a string variable in hex format.
Definition: color.cpp:64
Contains the info needed to instantiate a widget.
std::map< std::string, std::shared_ptr< builder_widget > > replacements_map
The replacements type is used to define replacement types.
The message for MESSAGE_SHOW_HELPTIP.
Definition: message.hpp:77
The message for MESSAGE_SHOW_TOOLTIP.
Definition: message.hpp:59
std::string definition
Parameters for the styled_widget.
virtual std::unique_ptr< widget > build() const=0
static const hotkey_command & get_command_by_command(HOTKEY_COMMAND command)
the execute_command argument was changed from HOTKEY_COMMAND to hotkey_command, to be able to call it...
Holds a 2D point.
Definition: point.hpp:25
#define LOG_HEADER
#define LOG_SCOPE_HEADER
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE_WITH_DEV_MESSAGE(cond, message, dev_message)