The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
scroll_text.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2023 - 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#define GETTEXT_DOMAIN "wesnoth-lib"
17
19
24#include "gettext.hpp"
25#include "wml_exception.hpp"
26
27#include <functional>
28
29#define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
30#define LOG_HEADER LOG_SCOPE_HEADER + ':'
31
32namespace gui2
33{
34
35// ------------ WIDGET -----------{
36
37REGISTER_WIDGET(scroll_text)
38
39scroll_text::scroll_text(const implementation::builder_scroll_text& builder)
40 : scrollbar_container(builder, type())
41 , state_(ENABLED)
42 , wrap_on_(false)
43 , text_alignment_(builder.text_alignment)
44 , editable_(builder.editable)
45 , max_size_(point(0,0))
46 , link_aware_(builder.link_aware)
47{
48 connect_signal<event::LEFT_BUTTON_DOWN>(
49 std::bind(&scroll_text::signal_handler_left_button_down, this, std::placeholders::_2),
51}
52
54{
55 if(content_grid()) {
56 return dynamic_cast<multiline_text*>(content_grid()->find("_text", false));
57 }
58
59 return nullptr;
60}
61
63{
65 widget->set_value(label);
66 widget->set_label(label);
67
68 bool resize_needed = !content_resize_request();
69 if(resize_needed && get_size() != point()) {
71 }
72 widget->goto_start_of_data();
73 }
74}
75
77{
79 return widget->get_value();
80 } else {
81 return "";
82 }
83}
84
86{
87 link_aware_ = l;
88
90 widget->set_link_aware(l);
91 }
92}
93
94void scroll_text::set_text_alignment(const PangoAlignment text_alignment)
95{
96 // Inherit.
98
99 text_alignment_ = text_alignment;
100
102 widget->set_text_alignment(text_alignment_);
103 }
104}
105
106void scroll_text::set_self_active(const bool active)
107{
108 state_ = active ? ENABLED : DISABLED;
109}
110
112{
113 return state_ != DISABLED;
114}
115
117{
118 return state_;
119}
120
122{
124 assert(text);
125
126 text->set_editable(is_editable());
127 text->set_label(get_label());
131}
132
133void scroll_text::place(const point& origin, const point& size) {
134 scrollbar_container::place(origin, size);
135
137 const rect& visible_area = content_visible_area();
138
139 if (widget->get_cursor_pos().x < visible_area.w/2.0) {
141 } else {
142 scroll_horizontal_scrollbar_by(widget->get_cursor_pos().x - visible_area.w/2.0);
143 }
144
145 if (widget->get_cursor_pos().y >= (widget->get_text_end_pos().y - visible_area.h/2.0)) {
146 if (widget->get_lines_count() > 1) {
148 } else {
150 }
151 } else if (widget->get_cursor_pos().y < visible_area.h/2.0) {
153 } else {
154 scroll_vertical_scrollbar_by(widget->get_cursor_pos().y - visible_area.h/2.0);
155 }
156
157 if (widget->get_length() == 0) {
160 }
161
162 set_max_size(widget->get_config_default_size());
163 }
164}
165
167{
169
170 if ((calc_size.x > max_size_.x) && (max_size_.x != 0)) {
171 calc_size.x = max_size_.x;
172 }
173
174 if ((calc_size.y > max_size_.y) && (max_size_.y != 0)) {
175 calc_size.y = max_size_.y;
176 }
177
178 return calc_size;
179}
180
182{
183 // ------ get vertical scrollbar size ------
185 ? point()
187
188 // ------ get horizontal scrollbar size ------
190 ? point()
192
193 // padding = 3
195}
196
197
198
199void scroll_text::set_can_wrap(bool can_wrap)
200{
202}
203
205{
206 return true;
207}
208
210{
211 DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
212
214}
215
216// }---------- DEFINITION ---------{
217
220{
221 DBG_GUI_P << "Parsing scroll text " << id;
222
223 load_resolutions<resolution>(cfg);
224}
225
227 : resolution_definition(cfg), grid(nullptr)
228{
229 // Note the order should be the same as the enum state_t is scroll_text.hpp.
230 state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_enabled", missing_mandatory_wml_tag("scroll_text", "state_enabled")));
231 state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_disabled", missing_mandatory_wml_tag("scroll_text", "state_disabled")));
232
233 auto child = VALIDATE_WML_CHILD(cfg, "grid", missing_mandatory_wml_tag("scroll_text", "grid"));
234 grid = std::make_shared<builder_grid>(child);
235}
236
237// }---------- BUILDER -----------{
238
239namespace implementation
240{
241
242builder_scroll_text::builder_scroll_text(const config& cfg)
244 , text_alignment(decode_text_alignment(cfg["text_alignment"]))
245 , editable(cfg["editable"].to_bool(true))
246 , link_aware(cfg["link_aware"].to_bool(false))
247{
248 // Scrollbar default to auto. AUTO_VISIBLE_FIRST_RUN doesn't work.
251 }
252
255 }
256}
257
258std::unique_ptr<widget> builder_scroll_text::build() const
259{
260 auto widget = std::make_unique<scroll_text>(*this);
261
262 const auto conf = widget->cast_config_to<scroll_text_definition>();
263 assert(conf);
264
265 widget->init_grid(*conf->grid);
266 widget->finalize_setup();
267
268 DBG_GUI_G << "Window builder: placed scroll text '" << id
269 << "' with definition '" << definition << "'.";
270
271 return widget;
272}
273
274} // namespace implementation
275
276// }------------ END --------------
277
278} // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
Base container class.
Definition grid.hpp:32
widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
Definition grid.cpp:645
void set_link_aware(bool l)
void set_max_size(point max_size)
Sets the size of the text beyond which scrollbars should be visible.
void signal_handler_left_button_down(const event::ui_event event)
virtual unsigned get_state() const override
See styled_widget::get_state.
std::string get_value()
multiline_text * get_internal_text_box()
PangoAlignment text_alignment_
void set_link_aware(bool l)
void set_can_wrap(bool can_wrap)
void finalize_subclass() override
Function for the subclasses to do their setup.
virtual void set_label(const t_string &label) override
bool is_editable() const
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
void place(const point &origin, const point &size) override
See widget::place.
point calculate_best_size() const override
See widget::calculate_best_size.
virtual bool get_active() const override
See styled_widget::get_active.
state_t state_
Current state of the widget.
virtual void set_text_alignment(const PangoAlignment text_alignment) override
See styled_widget::set_text_alignment.
bool can_wrap() const override
See widget::can_wrap.
@ END
Go to the end position.
Definition scrollbar.hpp:58
@ BEGIN
Go to begin position.
Definition scrollbar.hpp:53
Base class for creating containers with one or two scrollbar(s).
void scroll_vertical_scrollbar(const scrollbar_base::scroll_mode scroll)
Scrolls the vertical scrollbar.
@ AUTO_VISIBLE_FIRST_RUN
Like AUTO_VISIBLE, but when not needed upon the initial layout phase, the bars are not shown and no s...
@ AUTO_VISIBLE
The scrollbar is shown when the number of items is larger as the visible items.
virtual void place(const point &origin, const point &size) override
See widget::place.
void scroll_horizontal_scrollbar(const scrollbar_base::scroll_mode scroll)
Scrolls the horizontal scrollbar.
const rect & content_visible_area() const
virtual point calculate_best_size() const override
See widget::calculate_best_size.
void scroll_horizontal_scrollbar_by(const int pixels)
Scrolls the horizontal scrollbar by pixel.
bool content_resize_request(const bool force_sizing=false)
Notification if the content of a child needs a resize.
void scroll_vertical_scrollbar_by(const int pixels)
Scrolls the vertical scrollbar by pixel.
virtual void set_text_alignment(const PangoAlignment text_alignment)
virtual void set_label(const t_string &text)
virtual void set_use_markup(bool use_markup)
const t_string & get_label() const
bool get_use_markup() const
void set_editable(bool editable)
Set or unset whether text can be edited or not Text can only be copied and scrolled through when edit...
Base class for all widgets.
Definition widget.hpp:55
point get_best_size() const
Gets the best size for the widget.
Definition widget.cpp:203
visibility get_visible() const
Definition widget.cpp:506
point get_origin() const
Returns the screen origin of the widget.
Definition widget.cpp:311
point get_size() const
Returns the size of the widget.
Definition widget.cpp:316
window * get_window()
Get the parent window.
Definition widget.cpp:117
@ invisible
The user set the widget invisible, that means:
void keyboard_capture(widget *widget)
Definition window.cpp:1197
#define LOG_HEADER
const config * cfg
#define DBG_GUI_G
Definition log.hpp:41
#define DBG_GUI_P
Definition log.hpp:66
#define DBG_GUI_E
Definition log.hpp:35
ui_event
The event sent to the dispatcher.
Definition handler.hpp:115
Generic file dialog.
PangoAlignment decode_text_alignment(const std::string &alignment)
Converts a text alignment string to a text alignment.
Definition helper.cpp:84
Contains the implementation details for lexical_cast and shouldn't be used directly.
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
const std::size_t max_size
Definition sound.cpp:145
virtual std::unique_ptr< widget > build() const override
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
std::string definition
Parameters for the styled_widget.
std::vector< state_definition > state
scroll_text_definition(const config &cfg)
Holds a 2D point.
Definition point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49
std::string missing_mandatory_wml_tag(const std::string &section, const std::string &tag)
Returns a standard message for a missing wml child (tag).
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE_WML_CHILD(cfg, key, message)