The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
label.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
17 #include "gui/widgets/label.hpp"
18 
19 #include "gui/core/log.hpp"
20 
24 #include "gui/dialogs/message.hpp"
25 #include "gui/widgets/settings.hpp"
26 #include "gui/widgets/window.hpp"
27 
28 #include "desktop/clipboard.hpp"
29 #include "desktop/open.hpp"
30 #include "gettext.hpp"
31 
32 #include "utils/functional.hpp"
33 #include <string>
34 #include <sstream>
35 
36 namespace gui2
37 {
38 
39 // ------------ WIDGET -----------{
40 
41 REGISTER_WIDGET(label)
42 
44  : tcontrol(COUNT)
45  , state_(ENABLED)
46  , can_wrap_(false)
48  , link_aware_(false)
49  , link_color_("#ffff00")
50 {
51  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(&tlabel::signal_handler_left_button_click, this, _2, _3));
52  connect_signal<event::RIGHT_BUTTON_CLICK>(std::bind(&tlabel::signal_handler_right_button_click, this, _2, _3));
53 }
54 
55 bool tlabel::can_wrap() const
56 {
57  return can_wrap_ || characters_per_line_ != 0;
58 }
59 
61 {
62  return characters_per_line_;
63 }
64 
66 {
67  return link_aware_;
68 }
69 
71 {
72  return link_color_;
73 }
74 
75 void tlabel::set_active(const bool active)
76 {
77  if(get_active() != active) {
78  set_state(active ? ENABLED : DISABLED);
79  }
80 }
81 
82 bool tlabel::get_active() const
83 {
84  return state_ != DISABLED;
85 }
86 
87 unsigned tlabel::get_state() const
88 {
89  return state_;
90 }
91 
93 {
94  return false;
95 }
96 
97 void tlabel::set_characters_per_line(const unsigned characters_per_line)
98 {
99  characters_per_line_ = characters_per_line;
100 }
101 
102 void tlabel::set_link_aware(bool link_aware)
103 {
104  if(link_aware == link_aware_) {
105  return;
106  }
107 
108  link_aware_ = link_aware;
109  update_canvas();
110  set_is_dirty(true);
111 }
112 
114 {
115  if(color == link_color_) {
116  return;
117  }
118  link_color_ = color;
119  update_canvas();
120  set_is_dirty(true);
121 }
122 
123 void tlabel::set_state(const tstate state)
124 {
125  if(state != state_) {
126  state_ = state;
127  set_is_dirty(true);
128  }
129 }
130 
132 {
133  static const std::string type = "label";
134  return type;
135 }
136 
138 {
139  assert(config());
140 
142  conf = boost::dynamic_pointer_cast<const tlabel_definition::tresolution>(
143  config());
144 
145  assert(conf);
146 
147  set_link_aware(conf->link_aware);
148  set_link_color(conf->link_color);
149 }
150 
151 
152 void tlabel::signal_handler_left_button_click(const event::tevent /* event */, bool & handled)
153 {
154  DBG_GUI_E << "label click" << std::endl;
155 
156  if (!get_link_aware()) {
157  return; // without marking event as "handled".
158  }
159 
161  gui2::show_message(get_window()->video(), "", _("Opening links is not supported, contact your packager"), gui2::tmessage::auto_close);
162  handled = true;
163  return;
164  }
165 
166 
167  tpoint mouse = get_mouse_position();
168 
169  mouse.x -= get_x();
170  mouse.y -= get_y();
171 
172  std::string link = get_label_link(mouse);
173 
174  if (link.length() == 0) {
175  return ; // without marking event as "handled"
176  }
177 
178  DBG_GUI_E << "Clicked Link:\"" << link << "\"\n";
179 
180  const int res = gui2::show_message(get_window()->video(), _("Confirm"), _("Do you want to open this link?") + std::string("\n\n") + link, gui2::tmessage::yes_no_buttons);
181  if(res == gui2::twindow::OK) {
182  desktop::open_object(link);
183  }
184 
185  handled = true;
186 }
187 
188 void tlabel::signal_handler_right_button_click(const event::tevent /* event */, bool & handled)
189 {
190  DBG_GUI_E << "label right click" << std::endl;
191 
192  if (!get_link_aware()) {
193  return ; // without marking event as "handled".
194  }
195 
196  tpoint mouse = get_mouse_position();
197 
198  mouse.x -= get_x();
199  mouse.y -= get_y();
200 
201  std::string link = get_label_link(mouse);
202 
203  if (link.length() == 0) {
204  return ; // without marking event as "handled"
205  }
206 
207  DBG_GUI_E << "Right Clicked Link:\"" << link << "\"\n";
208 
210 
211  gui2::show_message(get_window()->video(), "", _("Copied link!"), gui2::tmessage::auto_close);
212 
213  handled = true;
214 }
215 
216 // }---------- DEFINITION ---------{
217 
219  : tcontrol_definition(cfg)
220 {
221  DBG_GUI_P << "Parsing label " << id << '\n';
222 
223  load_resolutions<tresolution>(cfg);
224 }
225 
226 /*WIKI
227  * @page = GUIWidgetDefinitionWML
228  * @order = 1_label
229  *
230  * == Label ==
231  *
232  * @macro = label_description
233  *
234  * Although the label itself has no event interaction it still has two states.
235  * The reason is that labels are often used as visual indication of the state
236  * of the widget it labels.
237  *
238  * Note: The above is outdated, if "link_aware" is enabled then there is interaction.
239  *
240  *
241  * The following states exist:
242  * * state_enabled, the label is enabled.
243  * * state_disabled, the label is disabled.
244  * @begin{parent}{name="gui/"}
245  * @begin{tag}{name="label_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
246  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
247  * @begin{table}{config}
248  * link_aware & f_bool & false & Whether the label is link aware. This means
249  * it is rendered with links highlighted,
250  * and responds to click events on those
251  * links. $
252  * link_color & string & #ffff00 & The color to render links with. This
253  * string will be used verbatim in pango
254  * markup for each link. $
255  * @end{table}
256  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
257  * @end{tag}{name="state_enabled"}
258  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
259  * @end{tag}{name="state_disabled"}
260  * @end{tag}{name="resolution"}
261  * @end{tag}{name="label_definition"}
262  * @end{parent}{name="gui/"}
263  */
266  , link_aware(cfg["link_aware"].to_bool(false))
267  , link_color(cfg["link_color"].str().size() > 0 ? cfg["link_color"].str() : "#ffff00")
268 {
269  // Note the order should be the same as the enum tstate is label.hpp.
270  state.push_back(tstate_definition(cfg.child("state_enabled")));
271  state.push_back(tstate_definition(cfg.child("state_disabled")));
272 }
273 
274 // }---------- BUILDER -----------{
275 
276 /*WIKI_MACRO
277  * @begin{macro}{label_description}
278  *
279  * A label displays a text, the text can be wrapped but no scrollbars
280  * are provided.
281  * @end{macro}
282  */
283 
284 /*WIKI
285  * @page = GUIWidgetInstanceWML
286  * @order = 2_label
287  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
288  * @begin{tag}{name="label"}{min=0}{max=-1}{super="generic/widget_instance"}
289  * == Label ==
290  *
291  * @macro = label_description
292  *
293  * List with the label specific variables:
294  * @begin{table}{config}
295  * wrap & bool & false & Is wrapping enabled for the label. $
296  * characters_per_line & unsigned & 0 &
297  * Sets the maximum number of characters per
298  * line. The amount is an approximate since the
299  * width of a character differs. E.g. iii is
300  * smaller than MMM. When the value is non-zero
301  * it also implies can_wrap is true.
302  * When having long strings wrapping them can
303  * increase readability, often 66 characters per
304  * line is considered the optimum for a one
305  * column text.
306  * text_alignment & h_align & "left" &
307  * How is the text aligned in the label. $
308  * @end{table}
309  * @end{tag}{name="label"}
310  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
311  */
312 
313 namespace implementation
314 {
315 
316 tbuilder_label::tbuilder_label(const config& cfg)
317  : tbuilder_control(cfg)
318  , wrap(cfg["wrap"].to_bool())
319  , characters_per_line(cfg["characters_per_line"])
320  , text_alignment(decode_text_alignment(cfg["text_alignment"]))
321 {
322 }
323 
325 {
326  tlabel* label = new tlabel();
327 
328  init_control(label);
329 
330  label->set_can_wrap(wrap);
333 
334  DBG_GUI_G << "Window builder: placed label '" << id << "' with definition '"
335  << definition << "'.\n";
336 
337  return label;
338 }
339 
340 } // namespace implementation
341 
342 // }------------ END --------------
343 
344 } // namespace gui2
Define the common log macros for the gui toolkit.
std::string link_color_
What color links will be rendered in.
Definition: label.hpp:113
#define DBG_GUI_P
Definition: log.hpp:69
void set_state(const tstate state)
Definition: label.cpp:123
virtual void set_active(const bool active) override
See tcontrol::set_active.
Definition: label.cpp:75
void signal_handler_left_button_click(const event::tevent event, bool &handled)
Left click signal handler: checks if we clicked on a hyperlink.
Definition: label.cpp:152
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
void set_can_wrap(const bool wrap)
Definition: label.hpp:60
tresolution_definition_ptr config()
Definition: control.hpp:299
This file contains the window object, this object is a top level container which has the event manage...
Enables auto close.
Definition: message.hpp:65
tresolution(const config &cfg)
Definition: label.cpp:264
int get_y() const
Definition: widget.cpp:289
Label showing a text.
Definition: label.hpp:29
PangoAlignment decode_text_alignment(const std::string &alignment)
Converts a text alignment string to a text alignment.
Definition: helper.cpp:92
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:435
virtual unsigned get_state() const override
See tcontrol::get_state.
Definition: label.cpp:87
Base class of a resolution, contains the common keys for a resolution.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
void init_control(tcontrol *control) const
Definition: control.cpp:675
std::string definition
Parameters for the control.
Definition: control.hpp:530
Desktop environment interaction functions.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
virtual bool can_wrap() const override
See twidget::can_wrap.
Definition: label.cpp:55
Dialog is closed with ok button.
Definition: window.hpp:125
This file contains the settings handling of the widget library.
void load_config_extra()
Inherited from tcontrol.
Definition: label.cpp:137
int y
y coordinate.
Definition: point.hpp:34
void show_message(CVideo &video, const std::string &title, const std::string &message, const std::string &button_caption, const bool auto_close, const bool message_use_markup)
Shows a message to the user.
Definition: message.cpp:143
bool can_wrap_
Holds the label can wrap or not.
Definition: label.hpp:95
tpoint get_mouse_position()
Returns the current mouse position.
Definition: helper.cpp:149
int get_x() const
Definition: widget.cpp:284
tevent
The event send to the dispatcher.
Definition: handler.hpp:54
GLuint color
Definition: glew.h:5801
tstate
Possible states of the widget.
Definition: label.hpp:78
Contains the state info for a resolution.
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
int x
x coordinate.
Definition: point.hpp:31
bool open_object(const std::string &path_or_url)
Opens the specified object with the default application configured for its type.
Definition: open.cpp:53
virtual void update_canvas()
Updates the canvas(ses).
Definition: control.cpp:364
unsigned characters_per_line_
The maximum number of characters per line.
Definition: label.hpp:102
GLuint res
Definition: glew.h:9258
#define DBG_GUI_E
Definition: log.hpp:35
virtual bool get_link_aware() const override
See tcontrol::get_link_aware.
Definition: label.cpp:65
tformula< bool > link_aware_
The link aware switch of the text.
Definition: canvas.cpp:1274
Holds a 2D point.
Definition: point.hpp:24
void set_characters_per_line(const unsigned set_characters_per_line)
Definition: label.cpp:97
tstate state_
Current state of the widget.
Definition: label.hpp:92
tlabel_definition(const config &cfg)
Definition: label.cpp:218
Base class for all visible items.
Definition: control.hpp:34
unsigned characters_per_line_
The number of characters per line.
Definition: canvas.cpp:1283
GLsizeiptr size
Definition: glew.h:1649
void set_link_color(const std::string &color)
Definition: label.cpp:113
bool open_object_is_supported()
Returns whether open_object() is supported/implemented for the current platform.
Definition: open.cpp:44
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:40
std::vector< tstate_definition > state
void set_text_alignment(const PangoAlignment text_alignment)
Definition: control.cpp:353
tformula< std::string > link_color_
The link color of the text.
Definition: canvas.cpp:1277
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
Base class for all widgets.
Definition: widget.hpp:49
void signal_handler_right_button_click(const event::tevent event, bool &handled)
Right click signal handler: checks if we clicked on a hyperlink, copied to clipboard.
Definition: label.cpp:188
std::string get_label_link(const gui2::tpoint &position) const
Definition: control.cpp:567
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
Definition: label.cpp:131
void set_link_aware(bool l)
Definition: label.cpp:102
virtual bool get_active() const override
See tcontrol::get_active.
Definition: label.cpp:82
twindow * get_window()
Get the parent window.
Definition: widget.cpp:116
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
virtual unsigned get_characters_per_line() const override
See tcontrol::get_characters_per_line.
Definition: label.cpp:60
#define DBG_GUI_G
Definition: log.hpp:41
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Shows a yes and no button.
Definition: message.hpp:75
bool link_aware_
Whether the label is link aware, rendering links with special formatting and handling click events...
Definition: label.hpp:108
virtual std::string get_link_color() const override
See tcontrol::get_link_aware.
Definition: label.cpp:70
Contains the implementation details for lexical_cast and shouldn't be used directly.
bool disable_click_dismiss() const override
See twidget::disable_click_dismiss.
Definition: label.cpp:92