The Battle for Wesnoth  1.17.17+dev
styled_widget.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2023
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 "gui/widgets/window.hpp"
30 #include "hotkey/hotkey_item.hpp"
31 #include "sdl/rect.hpp"
32 #include "video.hpp"
33 #include "wml_exception.hpp"
34 #include <functional>
35 
36 #include <algorithm>
37 #include <iomanip>
38 
39 #define LOG_SCOPE_HEADER \
40  "styled_widget(" + get_control_type() + ") [" + id() + "] " + __func__
41 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
42 
43 namespace gui2
44 {
45 
46 // ------------ WIDGET -----------{
47 
49  const std::string& control_type)
50  : widget(builder)
51  , definition_(builder.definition)
52  , label_(builder.label_string)
53  , use_markup_(builder.use_markup)
54  , use_tooltip_on_label_overflow_(builder.use_tooltip_on_label_overflow)
55  , tooltip_(builder.tooltip)
56  , help_message_(builder.help)
57  , config_(get_control(control_type, definition_))
58  , canvases_(config_->state.size()) // One canvas per state
59  , renderer_()
60  , text_maximum_width_(0)
61  , text_alignment_(PANGO_ALIGN_LEFT)
62  , text_ellipse_mode_(PANGO_ELLIPSIZE_END)
63  , shrunken_(false)
64 {
65  /*
66  * Fill in each canvas from the widget state definitons.
67  *
68  * Most widgets have a single canvas. However, some widgets such as toggle_panel
69  * and toggle_button have a variable canvas count determined by their definitions.
70  */
71  for(unsigned i = 0; i < config_->state.size(); ++i) {
72  canvases_[i].set_cfg(config_->state[i].canvas_cfg_);
73  }
74 
75  // Initialize all the canvas variables.
76  update_canvas();
77 
78  // Enable hover behavior if a tooltip was provided.
80 
81  connect_signal<event::SHOW_TOOLTIP>(std::bind(
82  &styled_widget::signal_handler_show_tooltip, this, std::placeholders::_2, std::placeholders::_3, std::placeholders::_5));
83 
84  connect_signal<event::SHOW_HELPTIP>(std::bind(
85  &styled_widget::signal_handler_show_helptip, this, std::placeholders::_2, std::placeholders::_3, std::placeholders::_5));
86 
87  connect_signal<event::NOTIFY_REMOVE_TOOLTIP>(std::bind(
88  &styled_widget::signal_handler_notify_remove_tooltip, this, std::placeholders::_2, std::placeholders::_3));
89 }
90 
92 {
93  /** @todo document this feature on the wiki. */
94  /** @todo do we need to add the debug colors here as well? */
95  widget_item::const_iterator itor = data.find("id");
96  if(itor != data.end()) {
97  set_id(itor->second);
98  }
99 
100  itor = data.find("linked_group");
101  if(itor != data.end()) {
102  set_linked_group(itor->second);
103  }
104 
105  itor = data.find("label");
106  if(itor != data.end()) {
107  set_label(itor->second);
108  }
109 
110  itor = data.find("tooltip");
111  if(itor != data.end()) {
112  set_tooltip(itor->second);
113  }
114 
115  itor = data.find("help");
116  if(itor != data.end()) {
117  set_help_message(itor->second);
118  }
119 
120  itor = data.find("use_markup");
121  if(itor != data.end()) {
122  set_use_markup(utils::string_bool(itor->second));
123  }
124 
125  itor = data.find("text_alignment");
126  if(itor != data.end()) {
128  }
129 }
130 
132 {
134 }
135 
137 {
138  return std::make_unique<iteration::walker::widget>(*this);
139 }
140 
142 {
143  assert(config_);
144 
145  point result(config_->min_width, config_->min_height);
146 
147  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
148  return result;
149 }
150 
152 {
153  assert(config_);
154 
155  point result(config_->default_width, config_->default_height);
156 
157  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
158  return result;
159 }
160 
162 {
163  assert(config_);
164 
165  point result(config_->max_width, config_->max_height);
166 
167  DBG_GUI_L << LOG_HEADER << " result " << result << ".";
168  return result;
169 }
170 
172 {
173  return 0;
174 }
175 
177 {
178  return false;
179 }
180 
182 {
183  return color_t::from_hex_string("ffff00");
184 }
185 
186 void styled_widget::layout_initialize(const bool full_initialization)
187 {
188  // Inherited.
189  widget::layout_initialize(full_initialization);
190 
191  if(full_initialization) {
192  shrunken_ = false;
193  }
194 }
195 
196 void styled_widget::request_reduce_width(const unsigned maximum_width)
197 {
198  assert(config_);
199 
200  if(!label_.empty() && can_wrap()) {
201 
203  point(), point(maximum_width - config_->text_extra_width, 0));
204 
205  size.x += config_->text_extra_width;
206  size.y += config_->text_extra_height;
207 
209 
210  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
211  << "' maximum_width " << maximum_width << " result " << size
212  << ".";
213 
214  } else if(label_.empty() || text_can_shrink()) {
217  size.x = std::min(size.x, std::max<int>(maximum_width, min_size.x));
219 
220  DBG_GUI_L << LOG_HEADER << " styled_widget " << id()
221  << " maximum_width " << maximum_width << " result " << size
222  << ".";
223  } else {
224  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
225  << "' failed; either no label or wrapping not allowed.";
226  }
227 }
228 
229 void styled_widget::request_reduce_height(const unsigned maximum_height)
230 {
231  if(!label_.empty()) {
232  // Do nothing
233  } else {
236  size.y = std::min(size.y, std::max<int>(maximum_height, min_size.y));
238 
239  DBG_GUI_L << LOG_HEADER << " styled_widget " << id()
240  << " maximum_height " << maximum_height << " result " << size
241  << ".";
242  }
243 }
244 
246 {
247  assert(config_);
248  if(label_.empty()) {
249  DBG_GUI_L << LOG_HEADER << " empty label return default.";
250  return get_config_default_size();
251  }
252 
253  const point minimum = get_config_default_size();
254  const point maximum = get_config_maximum_size();
255 
256  /**
257  * @todo The value send should subtract the border size
258  * and read it after calculation to get the proper result.
259  */
260  point result = get_best_text_size(minimum, maximum);
261  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
262  << "' result " << result << ".";
263  return result;
264 }
265 
266 void styled_widget::place(const point& origin, const point& size)
267 {
268  // resize canvasses
269  for(auto & canvas : canvases_)
270  {
272  }
273 
274  // Note we assume that the best size has been queried but otherwise it
275  // should return false.
277  && tooltip_.empty()) {
278 
280  }
281 
282  // inherited
283  widget::place(origin, size);
284 
285  // update the state of the canvas after the sizes have been set.
286  update_canvas();
287 }
288 
289 widget* styled_widget::find_at(const point& coordinate, const bool must_be_active)
290 {
291  return (widget::find_at(coordinate, must_be_active)
292  && (!must_be_active || get_active()))
293  ? this
294  : nullptr;
295 }
296 
298  const bool must_be_active) const
299 {
300  return (widget::find_at(coordinate, must_be_active)
301  && (!must_be_active || get_active()))
302  ? this
303  : nullptr;
304 }
305 
306 widget* styled_widget::find(const std::string& id, const bool must_be_active)
307 {
308  return (widget::find(id, must_be_active)
309  && (!must_be_active || get_active()))
310  ? this
311  : nullptr;
312 }
313 
314 const widget* styled_widget::find(const std::string& id, const bool must_be_active)
315  const
316 {
317  return (widget::find(id, must_be_active)
318  && (!must_be_active || get_active()))
319  ? this
320  : nullptr;
321 }
322 
324 {
325  if(label == label_) {
326  return;
327  }
328 
329  label_ = label;
331  update_canvas();
332  queue_redraw();
333 
334  // FIXME: This isn't the most elegant solution. Typically, we don't rely on the text rendering
335  // cache for anything except size calculations, but since we have link awareness now we need to
336  // update its text else `get_label_link` will return old results. I'm not actually sure why the
337  // results seem to only remain one invocation of `set_label` behind the current text, but that
338  // is what testing revealed (see https://github.com/wesnoth/wesnoth/pull/5363).
339  //
340  // -- vultraz, 2020-12-17
342 }
343 
344 void styled_widget::set_use_markup(bool use_markup)
345 {
346  if(use_markup == use_markup_) {
347  return;
348  }
349 
350  use_markup_ = use_markup;
351  update_canvas();
352  queue_redraw();
353 }
354 
355 void styled_widget::set_text_alignment(const PangoAlignment text_alignment)
356 {
357  if(text_alignment_ == text_alignment) {
358  return;
359  }
360 
361  text_alignment_ = text_alignment;
362  update_canvas();
363  queue_redraw();
364 }
365 
366 void styled_widget::set_text_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
367 {
368  if(text_ellipse_mode_ == ellipse_mode) {
369  return;
370  }
371 
372  text_ellipse_mode_ = ellipse_mode;
373  update_canvas();
374  queue_redraw();
375 }
376 
378 {
379  const int max_width = get_text_maximum_width();
380  const int max_height = get_text_maximum_height();
381 
382  // set label in canvases
383  for(auto & canvas : canvases_)
384  {
386  canvas.set_variable("text_markup", wfl::variant(use_markup_));
387  canvas.set_variable("text_link_aware", wfl::variant(get_link_aware()));
388 
389  // Possible TODO: consider making a formula_callable for colors.
390  color_t link_color = get_link_color();
391  std::vector<wfl::variant> link_color_as_list {
392  wfl::variant(link_color.r),
393  wfl::variant(link_color.g),
394  wfl::variant(link_color.b),
395  wfl::variant(link_color.a)
396  };
397 
398  canvas.set_variable("text_link_color", wfl::variant(link_color_as_list));
399  canvas.set_variable("text_alignment",
401  canvas.set_variable("text_maximum_width", wfl::variant(max_width));
402  canvas.set_variable("text_maximum_height", wfl::variant(max_height));
404  canvas.set_variable("text_characters_per_line",
406  }
407 }
408 
410 {
411  if (cached_text_font_size_ == 0) {
412  assert(config_);
413 
415  }
416  return cached_text_font_size_;
417 }
418 
420 {
421  assert(config_);
422 
424  : get_width() - config_->text_extra_width;
425 }
426 
428 {
429  assert(config_);
430 
431  return get_height() - config_->text_extra_height;
432 }
433 
435 {
436  DBG_GUI_D << LOG_HEADER << " label '" << debug_truncate(label_.str()) << "' size "
437  << get_rectangle() << ".";
438 
440 }
441 
443 {
444  /* DO NOTHING */
445 }
446 
447 point styled_widget::get_best_text_size(point minimum_size, point maximum_size) const
448 {
450 
451  assert(!label_.empty());
452 
453  // Try with the minimum wanted size.
454  const int maximum_width = text_maximum_width_ != 0
456  : maximum_size.x;
457 
458  /*
459  * NOTE: text rendering does *not* happen here. That happens in the text_shape
460  * canvas class. Instead, this just leverages the pango text rendering engine to
461  * calculate the area this widget will need to successfully render its text later.
462  */
463  renderer_
466  .set_family_class(config_->text_font_family)
468  .set_font_style(config_->text_font_style)
470  .set_maximum_width(maximum_width)
474 
475  if(get_characters_per_line() != 0 && !can_wrap()) {
477  << " Limited the number of characters per line, "
478  << "but wrapping is not set, output may not be as expected.";
479  }
480 
481  DBG_GUI_L << LOG_HEADER << "\n"
482  << std::boolalpha
483  << "Label: '" << debug_truncate(label_.str()) << "'\n\n"
484  << "Status:\n"
485  << "minimum_size: " << minimum_size << "\n"
486  << "maximum_size: " << maximum_size << "\n"
487  << "text_maximum_width_: " << text_maximum_width_ << "\n"
488  << "can_wrap: " << can_wrap() << "\n"
489  << "characters_per_line: " << get_characters_per_line() << "\n"
490  << "truncated: " << renderer_.is_truncated() << "\n"
491  << "renderer size: " << renderer_.get_size() << "\n"
492  << std::noboolalpha;
493 
494  const point border(config_->text_extra_width,
495  config_->text_extra_height);
496 
497  // If doesn't fit try the maximum.
498  if(renderer_.is_truncated() && !can_wrap()) {
499  // FIXME if maximum size is defined we should look at that
500  // but also we don't adjust for the extra text space yet!!!
501  maximum_size = point(config_->max_width,
502  config_->max_height);
503 
504  renderer_.set_maximum_width(maximum_size.x ? maximum_size.x - border.x : -1);
505  }
506 
507  // Get the resulting size.
508  point size = renderer_.get_size() + border;
509 
510  if(size.x < minimum_size.x) {
511  size.x = minimum_size.x;
512  }
513 
514  if(size.y < minimum_size.y) {
515  size.y = minimum_size.y;
516  }
517 
518  DBG_GUI_L << LOG_HEADER << " label '" << debug_truncate(label_.str())
519  << "' result " << size << ".";
520  return size;
521 }
522 
524  bool& handled,
525  const point& location)
526 {
527  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
528 
529  if(!tooltip_.empty()) {
530  std::string tip = tooltip_;
531  if(!help_message_.empty()) {
532  utils::string_map symbols;
533  symbols["hotkey"] = hotkey::get_names(
536 
539  }
540 
542  handled = fire(event::MESSAGE_SHOW_TOOLTIP, *this, message);
543  }
544 }
545 
547  bool& handled,
548  const point& location)
549 {
550  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
551 
552  if(!help_message_.empty()) {
554  handled = fire(event::MESSAGE_SHOW_HELPTIP, *this, message);
555  }
556 }
557 
559  bool& handled)
560 {
561  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
562 
563  /*
564  * This makes the class know the tip code rather intimately. An
565  * alternative is to add a message to the window to remove the tip.
566  * Might be done later.
567  */
569 
570  handled = true;
571 }
572 
573 std::string styled_widget::get_label_token(const point & position, const char * delim) const
574 {
575  return renderer_.get_token(position, delim);
576 }
577 
578 std::string styled_widget::get_label_link(const point & position) const
579 {
580  return renderer_.get_link(position);
581 }
582 
583 // }---------- BUILDER -----------{
584 
585 namespace implementation
586 {
587 
589  : builder_widget(cfg)
590  , definition(cfg["definition"])
591  , label_string(cfg["label"].t_str())
592  , tooltip(cfg["tooltip"].t_str())
593  , help(cfg["help"].t_str())
594  , use_tooltip_on_label_overflow(true)
595  , use_markup(cfg["use_markup"].to_bool(false))
596 {
597  if(definition.empty()) {
598  definition = "default";
599  }
600 
602  help.empty() || !tooltip.empty(),
603  _("Found a widget with a helptip and without a tooltip."),
604  formatter() << "id '" << id << "' label '" << label_string
605  << "' helptip '" << help << "'.");
606 
607 
608  DBG_GUI_P << "Window builder: found styled_widget with id '" << id
609  << "' and definition '" << definition << "'.";
610 }
611 
612 std::unique_ptr<widget> builder_styled_widget::build(const replacements_map& /*replacements*/) const
613 {
614  return build();
615 }
616 
617 } // namespace implementation
618 
619 // }------------ END --------------
620 
621 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:161
pango_text & set_font_style(const FONT_STYLE font_style)
Definition: text.cpp:384
point get_size()
Returns the size of the text, in drawing coordinates.
Definition: text.cpp:161
pango_text & set_characters_per_line(const unsigned characters_per_line)
Definition: text.cpp:419
pango_text & set_family_class(font::family_class fclass)
Definition: text.cpp:362
pango_text & set_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
Definition: text.cpp:455
pango_text & set_alignment(const PangoAlignment alignment)
Definition: text.cpp:475
pango_text & set_font_size(unsigned font_size)
Definition: text.cpp:372
pango_text & set_link_aware(bool b)
Definition: text.cpp:498
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:245
bool set_text(const std::string &text, const bool markedup)
Sets the text to render.
Definition: text.cpp:326
bool is_truncated() const
Has the text been truncated? This happens if it exceeds max width or height.
Definition: text.cpp:169
pango_text & set_maximum_width(int width)
Definition: text.cpp:403
pango_text & set_link_color(const color_t &color)
Definition: text.cpp:507
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:277
std::ostringstream wrapper.
Definition: formatter.hpp:40
A simple canvas which can be drawn upon.
Definition: canvas.hpp:44
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:137
void draw()
Draw the canvas' shapes onto the screen.
Definition: canvas.cpp:502
void set_size(const point &size)
Definition: canvas.cpp:586
Main class to show messages to the user.
Definition: message.hpp:36
Class to show the tips.
Definition: tooltip.cpp:58
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:76
void set_wants_mouse_hover(const bool hover=true)
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:58
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.
virtual void set_label(const t_string &label)
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 void 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.
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 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.
virtual void impl_draw_foreground() override
See widget::impl_draw_foreground.
Base class for all widgets.
Definition: widget.hpp:54
void set_layout_size(const point &size)
Definition: widget.cpp:336
point get_best_size() const
Gets the best size for the widget.
Definition: widget.cpp:194
virtual void place(const point &origin, const point &size)
Places the widget.
Definition: widget.cpp:239
void set_id(const std::string &id)
Definition: widget.cpp:99
virtual void layout_initialize(const bool full_initialization)
How the layout engine works.
Definition: widget.cpp:168
void set_linked_group(const std::string &linked_group)
Definition: widget.cpp:346
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:442
visibility get_visible() const
Definition: widget.cpp:483
virtual widget * find(const std::string &id, const bool must_be_active)
Returns a widget with the wanted id.
Definition: widget.cpp:541
unsigned get_width() const
Definition: widget.cpp:326
unsigned get_height() const
Definition: widget.cpp:331
const std::string & id() const
Definition: widget.cpp:111
@ 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:311
virtual widget * find_at(const point &coordinate, const bool must_be_active)
Returns the widget at the wanted coordinates.
Definition: widget.cpp:530
virtual bool can_wrap() const
Can the widget wrap.
Definition: widget.cpp:217
bool empty() const
Definition: tstring.hpp:187
const std::string & str() const
Definition: tstring.hpp:191
This file contains the definitions for the gui2::event::message class.
std::size_t i
Definition: function.cpp:968
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:217
This file contains the window object, this object is a top level container which has the event manage...
#define log_scope2(domain, description)
Definition: log.hpp:241
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:193
void remove()
Removes a tip.
Definition: tooltip.cpp:111
static std::unique_ptr< tooltip > tip
Definition: tooltip.cpp:79
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:43
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:96
std::string_view debug_truncate(std::string_view text)
Returns a truncated version of the text.
Definition: helper.cpp:119
std::map< std::string, t_string > widget_item
Definition: widget.hpp:32
PangoAlignment decode_text_alignment(const std::string &alignment)
Converts a text alignment string to a text alignment.
Definition: helper.cpp:60
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:75
Definition: help.cpp:57
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:87
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:199
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(const std::string &c)
Creates a new color_t object from a string variable in hex format.
Definition: color.cpp:62
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)