The Battle for Wesnoth  1.15.2+dev
scroll_label.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://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 
18 
19 #include "gui/widgets/label.hpp"
21 #include "gui/core/log.hpp"
24 #include "gui/widgets/settings.hpp"
26 #include "gui/widgets/spacer.hpp"
27 #include "gui/widgets/window.hpp"
28 #include "gettext.hpp"
29 
30 #include "utils/functional.hpp"
31 
32 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
33 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
34 
35 namespace gui2
36 {
37 
38 // ------------ WIDGET -----------{
39 
40 REGISTER_WIDGET(scroll_label)
41 
42 scroll_label::scroll_label(const implementation::builder_scroll_label& builder)
43  : scrollbar_container(builder, type())
44  , state_(ENABLED)
45  , wrap_on_(builder.wrap_on)
46  , text_alignment_(builder.text_alignment)
47 {
48  connect_signal<event::LEFT_BUTTON_DOWN>(
51 }
52 
54 {
55  if(content_grid()) {
56  return dynamic_cast<label*>(content_grid()->find("_label", false));
57  }
58 
59  return nullptr;
60 }
61 
63 {
64  // Inherit.
66 
68  widget->set_label(lbl);
69 
70  bool resize_needed = !content_resize_request();
71  if(resize_needed && get_size() != point()) {
73  }
74  }
75 }
76 
77 void scroll_label::set_text_alignment(const PangoAlignment text_alignment)
78 {
79  // Inherit.
80  styled_widget::set_text_alignment(text_alignment);
81 
82  text_alignment_ = text_alignment;
83 
85  widget->set_text_alignment(text_alignment_);
86  }
87 }
88 
89 void scroll_label::set_use_markup(bool use_markup)
90 {
91  // Inherit.
93 
95  widget->set_use_markup(use_markup);
96  }
97 }
98 
99 void scroll_label::set_text_alpha(unsigned short alpha)
100 {
101  if(label* widget = get_internal_label()) {
102  widget->set_text_alpha(alpha);
103  }
104 }
105 
107 {
108  if(label* widget = get_internal_label()) {
109  widget->set_link_aware(l);
110  }
111 }
112 
113 void scroll_label::set_self_active(const bool active)
114 {
115  state_ = active ? ENABLED : DISABLED;
116 }
117 
119 {
120  return state_ != DISABLED;
121 }
122 
123 unsigned scroll_label::get_state() const
124 {
125  return state_;
126 }
127 
129 {
130  label* lbl = get_internal_label();
131  assert(lbl);
132 
133  lbl->set_label(get_label());
134  lbl->set_can_wrap(wrap_on_);
137 }
138 
140 {
141  label* lbl = get_internal_label();
142  assert(lbl);
143 
144  wrap_on_ = can_wrap;
145  lbl->set_can_wrap(wrap_on_);
146 }
147 
149 {
150  return wrap_on_;
151 }
152 
154 {
155  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
156 
157  get_window()->keyboard_capture(this);
158 }
159 
160 // }---------- DEFINITION ---------{
161 
164 {
165  DBG_GUI_P << "Parsing scroll label " << id << '\n';
166 
167  load_resolutions<resolution>(cfg);
168 }
169 
170 /*WIKI
171  * @page = GUIWidgetDefinitionWML
172  * @order = 1_scroll_label
173  *
174  * == Scroll label ==
175  *
176  * @macro = scroll_label_description
177  *
178  * @begin{parent}{name="gui/"}
179  * This widget is slower as a normal label widget so only use this widget
180  * when the scrollbar is required (or expected to become required).
181  * @begin{tag}{name="scroll_label_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
182  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
183  * @begin{table}{config}
184  * grid & grid & & A grid containing the widgets for main
185  * widget. $
186  * @end{table}
187  * @allow{link}{name="gui/window/resolution/grid"}
188  * TODO we need one definition for a vertical scrollbar since this is the second
189  * time we use it.
190  *
191  * @begin{table}{dialog_widgets}
192  * _content_grid & & grid & m & A grid which should only contain one
193  * label widget. $
194  * _scrollbar_grid & & grid & m & A grid for the scrollbar
195  * (Merge with listbox info.) $
196  * @end{table}
197  * @begin{tag}{name="content_grid"}{min=0}{max=1}{super="gui/window/resolution/grid"}
198  * @end{tag}{name="content_grid"}
199  * @begin{tag}{name="scrollbar_grid"}{min=0}{max=1}{super="gui/window/resolution/grid"}
200  * @end{tag}{name="scrollbar_grid"}
201  * The following states exist:
202  * * state_enabled, the scroll label is enabled.
203  * * state_disabled, the scroll label is disabled.
204  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
205  * @end{tag}{name="state_enabled"}
206  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
207  * @end{tag}{name="state_disabled"}
208  * @end{tag}{name="resolution"}
209  * @end{tag}{name="scroll_label_definition"}
210  * @end{parent}{name="gui/"}
211  */
213  : resolution_definition(cfg), grid(nullptr)
214 {
215  // Note the order should be the same as the enum state_t is scroll_label.hpp.
216  state.emplace_back(cfg.child("state_enabled"));
217  state.emplace_back(cfg.child("state_disabled"));
218 
219  const config& child = cfg.child("grid");
220  VALIDATE(child, _("No grid defined."));
221 
222  grid = std::make_shared<builder_grid>(child);
223 }
224 
225 // }---------- BUILDER -----------{
226 
227 /*WIKI_MACRO
228  * @begin{macro}{scroll_label_description}
229  *
230  * A scroll label is a label that wraps its text and also has a
231  * vertical scrollbar. This way a text can't be too long to be shown
232  * for this widget.
233  * @end{macro}
234  */
235 
236 /*WIKI
237  * @page = GUIWidgetInstanceWML
238  * @order = 2_scroll_label
239  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
240  * @begin{tag}{name="scroll_label"}{min="0"}{max="-1"}{super="generic/widget_instance"}
241  * == Scroll label ==
242  *
243  * @macro = scroll_label_description
244  *
245  * List with the scroll label specific variables:
246  * @begin{table}{config}
247  * vertical_scrollbar_mode & scrollbar_mode & initial_auto &
248  * Determines whether or not to show the
249  * scrollbar. $
250  * horizontal_scrollbar_mode & scrollbar_mode & initial_auto &
251  * Determines whether or not to show the
252  * scrollbar. $
253  * wrap & boolean & true & Determines whether the text of the
254  * label is allowed to wrap. $
255  * @end{table}
256  * @end{tag}{name="scroll_label"}
257  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
258  */
259 
260 namespace implementation
261 {
262 
263 builder_scroll_label::builder_scroll_label(const config& cfg)
265  , vertical_scrollbar_mode(get_scrollbar_mode(cfg["vertical_scrollbar_mode"]))
266  , horizontal_scrollbar_mode(get_scrollbar_mode(cfg["horizontal_scrollbar_mode"]))
267  , wrap_on(cfg["wrap"].to_bool(true))
268  , text_alignment(decode_text_alignment(cfg["text_alignment"]))
269 {
270 }
271 
273 {
274  scroll_label* widget = new scroll_label(*this);
275 
278 
279  const auto conf = widget->cast_config_to<scroll_label_definition>();
280  assert(conf);
281 
282  widget->init_grid(conf->grid);
283  widget->finalize_setup();
284 
285  DBG_GUI_G << "Window builder: placed scroll label '" << id
286  << "' with definition '" << definition << "'.\n";
287 
288  return widget;
289 }
290 
291 } // namespace implementation
292 
293 // }------------ END --------------
294 
295 } // namespace gui2
Define the common log macros for the gui toolkit.
Base class of a resolution, contains the common keys for a resolution.
void keyboard_capture(widget *widget)
Definition: window.cpp:1281
#define DBG_GUI_P
Definition: log.hpp:68
config & child(config_key_type 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:420
virtual unsigned get_state() const override
See styled_widget::get_state.
std::vector< state_definition > state
void set_horizontal_scrollbar_mode(const scrollbar_mode scrollbar_mode)
virtual void set_use_markup(bool use_markup) override
See styled_widget::set_use_markup.
void set_can_wrap(const bool wrap)
Definition: label.hpp:65
bool get_use_markup() const
virtual void place(const point &origin, const point &size) override
See widget::place.
void finalize_subclass() override
Function for the subclasses to do their setup.
This file contains the window object, this object is a top level container which has the event manage...
void set_vertical_scrollbar_mode(const scrollbar_mode scrollbar_mode)
PangoAlignment text_alignment_
Base class for all widgets.
Definition: widget.hpp:47
Label showing a text.
Definition: label.hpp:32
PangoAlignment decode_text_alignment(const std::string &alignment)
Converts a text alignment string to a text alignment.
Definition: helper.cpp:63
void signal_handler_left_button_down(const event::ui_event event)
void set_text_alpha(unsigned short alpha)
virtual void set_label(const t_string &label) override
See styled_widget::set_label.
Generic file dialog.
Definition: field-fwd.hpp:22
state_t state_
Current state of the widget.
virtual void set_label(const t_string &label)
Base container class.
Definition: grid.hpp:30
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:91
std::string definition
Parameters for the styled_widget.
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
This file contains the settings handling of the widget library.
virtual bool get_active() const override
See styled_widget::get_active.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Definition: grid.cpp:655
virtual void set_text_alignment(const PangoAlignment text_alignment)
bool content_resize_request(const bool force_sizing=false)
Notification if the content of a child needs a resize.
virtual void set_use_markup(bool use_markup)
void set_link_aware(bool l)
Label showing a text.
void init_grid(const std::shared_ptr< builder_grid > &grid_builder)
Initializes and builds the grid.
virtual void set_text_alignment(const PangoAlignment text_alignment) override
See styled_widget::set_text_alignment.
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
label * get_internal_label()
Base class for creating containers with one or two scrollbar(s).
#define DBG_GUI_E
Definition: log.hpp:34
std::shared_ptr< const typename T::resolution > cast_config_to() const
Casts the current resolution definition config to the respective type of a derived widget...
window * get_window()
Get the parent window.
Definition: widget.cpp:114
Holds a 2D point.
Definition: point.hpp:23
void set_can_wrap(bool can_wrap)
scrollbar_mode get_scrollbar_mode(const std::string &scrollbar_mode)
Returns the scrollbar mode flags.
Definition: helper.cpp:120
point get_size() const
Returns the size of the widget.
Definition: widget.cpp:302
const t_string & get_label() const
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
#define LOG_HEADER
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
bool can_wrap() const override
See widget::can_wrap.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
#define DBG_GUI_G
Definition: log.hpp:40
scroll_label_definition(const config &cfg)
point get_origin() const
Returns the screen origin of the widget.
Definition: widget.cpp:297
Contains the implementation details for lexical_cast and shouldn&#39;t be used directly.
ui_event
The event send to the dispatcher.
Definition: handler.hpp:55