The Battle for Wesnoth  1.19.5+dev
multiline_text.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2023 - 2024
3  by Subhraman Sarkar (babaissarkar) <suvrax@gmail.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  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 #pragma once
16 
18 #include "gui/widgets/text_box.hpp"
19 #include "gui/widgets/window.hpp"
21 
22 namespace gui2
23 {
24 namespace implementation
25 {
26 struct builder_multiline_text;
27 }
28 
29 // ------------ WIDGET -----------{
30 
32 {
34 
35 public:
37 
38  /** See @ref widget::can_wrap. */
39  bool can_wrap() const override
40  {
41  return false;
42  }
43 
44  /** Saves the text in the widget to the history. */
46  {
48  }
49 
50  /***** ***** ***** setters / getters for members ***** ****** *****/
51 
52  void set_history(const std::string& id)
53  {
55  }
56 
57  void set_max_input_length(const std::size_t length)
58  {
59  max_input_length_ = length;
60  }
61 
62  void set_hint_data(const std::string& text, const std::string& image)
63  {
64  hint_text_ = text;
66 
67  update_canvas();
68  }
69 
70  void clear()
71  {
72  set_value("");
73  }
74 
76  {
78  }
79 
81  {
82  unsigned line_num = get_line_number(get_selection_start());
83  return get_cursor_position(get_line_end_offset(line_num)).x;
84  }
85 
87  {
89  }
90 
91 protected:
92  /***** ***** ***** ***** layout functions ***** ***** ***** *****/
93 
94  /** See @ref widget::place. */
95  virtual void place(const point& origin, const point& size) override;
96 
97  /***** ***** ***** ***** Inherited ***** ***** ***** *****/
98 
99  /** See @ref styled_widget::update_canvas. */
100  virtual void update_canvas() override;
101 
102  /** Inherited from text_box_base. */
103  void insert_char(const std::string& unicode) override
104  {
106  update_layout();
107  }
108 
109  /** Inherited from text_box_base */
110  void set_cursor(const std::size_t offset, const bool select) override
111  {
112  text_box_base::set_cursor(offset, select);
113  // Whenever cursor moves, this tells scroll_text to update the scrollbars
114  update_layout();
115  }
116 
117 public:
118  /** Inherited from text_box_base. */
119  void goto_end_of_line(const bool select = false) override
120  {
121  unsigned line_num = get_line_number(get_selection_start());
122  set_cursor(get_line_end_offset(line_num), select);
123  }
124 
125  /** Inherited from text_box_base. */
126  void goto_start_of_line(const bool select = false) override
127  {
128  unsigned line_num = get_line_number(get_selection_start());
129  set_cursor(get_line_start_offset(line_num), select);
130  }
131 
132  /** Inherited from text_box_base. */
133  void goto_end_of_data(const bool select = false) override
134  {
136  update_layout();
137  }
138 
139  /** Inherited from text_box_base. */
140  void goto_start_of_data(const bool select = false) override
141  {
143  update_layout();
144  }
145 
146  /** See @ref styled_widget::get_link_aware. */
147  virtual bool get_link_aware() const override
148  {
149  return link_aware_;
150  }
151 
152  void set_link_aware(bool l);
153 
154 private:
155  /** Inherited from text_box_base. */
156  void paste_selection() override
157  {
159  update_layout();
160  }
161 
162  /** Inherited from text_box_base. */
163  void delete_char(const bool before_cursor) override;
164 
165  /** Inherited from text_box_base. */
166  void delete_selection() override;
167 
168  void handle_mouse_selection(point mouse, const bool start_selection);
169 
170 private:
171  /** The history text for this widget. */
173 
174  /** The maximum length of the text input. */
175  std::size_t max_input_length_;
176 
177  /**
178  * The x offset in the widget where the text starts.
179  *
180  * This value is needed to translate a location in the widget to a location
181  * in the text.
182  */
183  unsigned text_x_offset_;
184 
185  /**
186  * The y offset in the widget where the text starts.
187  *
188  * Needed to determine whether a click is on the text.
189  */
190  unsigned text_y_offset_;
191 
192  /**
193  * The height of the text itself.
194  *
195  * Needed to determine whether a click is on the text.
196  */
197  unsigned text_height_;
198 
199  /** Updates text_x_offset_ and text_y_offset_. */
200  void update_offsets();
201 
202  /** Is the mouse in dragging mode, this affects selection in mouse move */
203  bool dragging_;
204 
205  /**
206  * Whether the text area is link aware, rendering links with special formatting
207  * and handling click events.
208  */
210 
211  /** Helper text to display (such as "Search") if the text box is empty. */
212  std::string hint_text_;
213 
214  /** Image (such as a magnifying glass) that accompanies the help text. */
215  std::string hint_image_;
216 
217  /**
218  * Utility function to calculate the offset of the end of the line
219  */
220  unsigned get_line_end_offset(unsigned line_no);
221 
222  /**
223  * Utility function to calculate the offset of the end of the line
224  */
225  unsigned get_line_start_offset(unsigned line_no);
226 
227  /** Update layout. To be called when text size changes */
228  void update_layout() {
229  set_label(get_value());
231  }
232 
233 
234  /**
235  * Inherited from text_box_base.
236  *
237  * Unmodified Handled.
238  * Control Ignored.
239  * Shift Ignored.
240  * Alt Ignored.
241  */
242  void handle_key_up_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
243 
244  /**
245  * Inherited from text_box_base.
246  *
247  * Unmodified Handled.
248  * Control Ignored.
249  * Shift Ignored.
250  * Alt Ignored.
251  */
252  void handle_key_down_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
253 
254  /**
255  * Inherited from text_box_base.
256  *
257  * Unmodified Handled.
258  * Control Ignored.
259  * Shift Ignored.
260  * Alt Ignored.
261  */
262  void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) override
263  {
264  text_box_base::handle_key_left_arrow(modifier, handled);
265  update_layout();
266  }
267 
268  /**
269  * Inherited from text_box_base.
270  *
271  * Unmodified Handled.
272  * Control Ignored.
273  * Shift Ignored.
274  * Alt Ignored.
275  */
276  void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) override
277  {
278  text_box_base::handle_key_right_arrow(modifier, handled);
279  update_layout();
280  }
281 
282  /**
283  * Goes one item up in the history.
284  *
285  * @returns True if there's a history, false otherwise.
286  */
287  bool history_up();
288 
289  /**
290  * Goes one item down in the history.
291  *
292  * @returns True if there's a history, false otherwise.
293  */
294  bool history_down();
295 
296  /** Inherited from text_box_base. */
297  void handle_key_tab(SDL_Keymod modifier, bool& handled) override;
298 
299  /** Inherited from text_box_base. */
300  void handle_key_enter(SDL_Keymod modifier, bool& handled) override;
301 
302  /** Inherited from text_box_base. */
303  void handle_key_clear_line(SDL_Keymod modifier, bool& handled) override;
304 
305 public:
306  /** Static type getter that does not rely on the widget being constructed. */
307  static const std::string& type();
308 
309 private:
310 
311  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
312  virtual const std::string& get_control_type() const override;
313 
314  /***** ***** ***** signal handlers ***** ****** *****/
315 
317  bool& handled,
318  const point& coordinate);
319 
321  bool& handled);
322 
324  bool& handled);
325 
327  bool& handled);
328 };
329 
330 // }---------- DEFINITION ---------{
331 
333 {
334  explicit multiline_text_definition(const config& cfg);
335 
337  {
338  explicit resolution(const config& cfg);
339 
342  };
343 };
344 
345 // }---------- BUILDER -----------{
346 
347 namespace implementation
348 {
349 
351 {
352 public:
353  explicit builder_multiline_text(const config& cfg);
354 
356 
357  virtual std::unique_ptr<widget> build() const override;
358 
359  std::string history;
360 
361  std::size_t max_input_length;
362 
364  std::string hint_image;
365 
366  bool editable;
367  bool wrap;
369 };
370 
371 } // namespace implementation
372 
373 // }------------ END --------------
374 
375 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
void handle_key_down_arrow(SDL_Keymod, bool &handled) override
Inherited from text_box_base.
bool dragging_
Is the mouse in dragging mode, this affects selection in mouse move.
unsigned text_y_offset_
The y offset in the widget where the text starts.
unsigned text_x_offset_
The x offset in the widget where the text starts.
virtual void place(const point &origin, const point &size) override
See widget::place.
void handle_key_right_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from text_box_base.
bool link_aware_
Whether the text area is link aware, rendering links with special formatting and handling click event...
void set_history(const std::string &id)
multiline_text(const implementation::builder_multiline_text &builder)
void set_link_aware(bool l)
void set_max_input_length(const std::size_t length)
bool history_up()
Goes one item up in the history.
void delete_selection() override
Inherited from text_box_base.
unsigned text_height_
The height of the text itself.
void handle_key_left_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from text_box_base.
bool can_wrap() const override
See widget::can_wrap.
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
void signal_handler_mouse_motion(const event::ui_event event, bool &handled, const point &coordinate)
void update_offsets()
Updates text_x_offset_ and text_y_offset_.
void handle_key_enter(SDL_Keymod modifier, bool &handled) override
Inherited from text_box_base.
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
virtual bool get_link_aware() const override
See styled_widget::get_link_aware.
void paste_selection() override
Inherited from text_box_base.
void goto_start_of_data(const bool select=false) override
Inherited from text_box_base.
bool history_down()
Goes one item down in the history.
unsigned get_line_end_offset(unsigned line_no)
Utility function to calculate the offset of the end of the line.
void handle_mouse_selection(point mouse, const bool start_selection)
std::string hint_text_
Helper text to display (such as "Search") if the text box is empty.
void save_to_history()
Saves the text in the widget to the history.
void signal_handler_left_button_down(const event::ui_event event, bool &handled)
void delete_char(const bool before_cursor) override
Inherited from text_box_base.
virtual void update_canvas() override
See styled_widget::update_canvas.
std::string hint_image_
Image (such as a magnifying glass) that accompanies the help text.
void goto_end_of_line(const bool select=false) override
Inherited from text_box_base.
void handle_key_tab(SDL_Keymod modifier, bool &handled) override
Inherited from text_box_base.
unsigned get_line_start_offset(unsigned line_no)
Utility function to calculate the offset of the end of the line.
void handle_key_clear_line(SDL_Keymod modifier, bool &handled) override
Inherited from text_box_base.
void goto_start_of_line(const bool select=false) override
Inherited from text_box_base.
std::size_t max_input_length_
The maximum length of the text input.
void signal_handler_left_button_double_click(const event::ui_event event, bool &handled)
void update_layout()
Update layout.
void set_cursor(const std::size_t offset, const bool select) override
Inherited from text_box_base.
void handle_key_up_arrow(SDL_Keymod, bool &handled) override
Inherited from text_box_base.
void insert_char(const std::string &unicode) override
Inherited from text_box_base.
void set_hint_data(const std::string &text, const std::string &image)
void goto_end_of_data(const bool select=false) override
Inherited from text_box_base.
text_history history_
The history text for this widget.
void signal_handler_left_button_up(const event::ui_event event, bool &handled)
virtual void set_label(const t_string &text)
Abstract base class for text items.
std::size_t get_length() const
Wrapper function, returns length of the text in pango column offsets.
virtual void insert_char(const std::string &unicode)
Inserts a character at the cursor.
virtual void handle_key_left_arrow(SDL_Keymod modifier, bool &handled)
Left arrow key pressed.
std::string get_value() const
const std::string & text() const
point get_cursor_position(const unsigned column, const unsigned line=0) const
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
virtual void paste_selection()
Pastes the current selection.
virtual void handle_key_right_arrow(SDL_Keymod modifier, bool &handled)
Right arrow key pressed.
virtual void set_cursor(const std::size_t offset, const bool select)
Moves the cursor at the wanted position.
virtual void goto_end_of_data(const bool select=false)
Moves the cursor to the end of all text.
std::size_t get_selection_start() const
virtual void goto_start_of_data(const bool select=false)
Moves the cursor to the beginning of the data.
int get_line_number(const unsigned offset)
Wrapper function, return the line number given the byte index.
Class for text input history.
Definition: text_box.hpp:37
static text_history get_history(const std::string &id, const bool enabled)
Gets history that matches id.
Definition: text_box.cpp:40
void push(const std::string &text)
Push string into the history.
Definition: text_box.cpp:47
window * get_window()
Get the parent window.
Definition: widget.cpp:117
void invalidate_layout()
Updates the size of the window.
Definition: window.cpp:761
This file contains the window object, this object is a top level container which has the event manage...
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
Generic file dialog.
Functions to load and save images from/to disk.
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
virtual std::unique_ptr< widget > build() const override
virtual std::unique_ptr< widget > build() const=0
multiline_text_definition(const config &cfg)
Holds a 2D point.
Definition: point.hpp:25