The Battle for Wesnoth  1.19.0-dev
multiline_text.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2023 - 2024
3  by babaissarkar(Subhraman Sarkar) <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"
20 
21 namespace gui2
22 {
23 namespace implementation
24 {
25 struct builder_multiline_text;
26 }
27 
28 // ------------ WIDGET -----------{
29 
30 /**
31  * @ingroup GUIWidgetWML
32  *
33  * Base class for a multiline text area.
34  *
35  * The resolution for a text box also contains the following keys:
36  * Key |Type |Default |Description
37  * -------------|----------------------------------------|---------|-----------
38  * text_x_offset| @ref guivartype_f_unsigned "f_unsigned"|"" |The x offset of the text in the text box. This is needed for the code to determine where in the text the mouse clicks, so it can set the cursor properly.
39  * text_y_offset| @ref guivartype_f_unsigned "f_unsigned"|"" |The y offset of the text in the text box.
40  * The following states exist:
41  * * state_enabled - the text box is enabled.
42  * * state_disabled - the text box is disabled.
43  * * state_focussed - the text box has the focus of the keyboard.
44  * The following variables exist:
45  * Key |Type |Default |Description
46  * -------------|------------------------------------|---------|-----------
47  * label | @ref guivartype_t_string "t_string"|"" |The initial text of the text box.
48  * history | @ref guivartype_string "string" |"" |The name of the history for the text box. A history saves the data entered in a text box between the games. With the up and down arrow it can be accessed. To create a new history item just add a new unique name for this field and the engine will handle the rest.
49  * editable | @ref guivartype_bool "bool" |"true" |If the contents of the text box can be edited.
50  */
52 {
54 
55 public:
57 
58  /** See @ref widget::can_wrap. */
59  bool can_wrap() const override
60  {
61  return false;
62  }
63 
64  /** Saves the text in the widget to the history. */
66  {
68  }
69 
70  /***** ***** ***** setters / getters for members ***** ****** *****/
71 
72  void set_history(const std::string& id)
73  {
75  }
76 
77  void set_max_input_length(const std::size_t length)
78  {
79  max_input_length_ = length;
80  }
81 
82  void set_hint_data(const std::string& text, const std::string& image)
83  {
84  hint_text_ = text;
86 
87  update_canvas();
88  }
89 
90  void clear()
91  {
92  set_value("");
93  }
94 
95  unsigned get_line_no()
96  {
98  return line_num_;
99  }
100 
102  {
104  }
105 
107  {
109  }
110 
112  {
114  }
115 
116 protected:
117  /***** ***** ***** ***** layout functions ***** ***** ***** *****/
118 
119  /** See @ref widget::place. */
120  virtual void place(const point& origin, const point& size) override;
121 
122  /***** ***** ***** ***** Inherited ***** ***** ***** *****/
123 
124  /** See @ref styled_widget::update_canvas. */
125  virtual void update_canvas() override;
126 
127  /** Inherited from text_box_base. */
128  void insert_char(const std::string& unicode) override
129  {
131  update_layout();
132  }
133 
134  /** Inherited from text_box_base */
135  void set_cursor(const std::size_t offset, const bool select) override
136  {
137  text_box_base::set_cursor(offset, select);
139  // Whenever cursor moves, this tells scroll_text to update the scrollbars
140  update_layout();
141  }
142 
143  /** Inherited from text_box_base. */
144  void goto_end_of_line(const bool select = false) override
145  {
148  }
149 
150  /** Inherited from text_box_base. */
151  void goto_start_of_line(const bool select = false) override
152  {
155  }
156 
157  /** Inherited from text_box_base. */
158  void goto_end_of_data(const bool select = false) override
159  {
161  update_layout();
162  }
163 
164  /** Inherited from text_box_base. */
165  void goto_start_of_data(const bool select = false) override
166  {
168  update_layout();
169  }
170 
171  /** Inherited from text_box_base. */
172  void paste_selection(const bool mouse) override
173  {
175  update_layout();
176  }
177 
178  /** Inherited from text_box_base. */
179  void delete_char(const bool before_cursor) override;
180 
181  /** Inherited from text_box_base. */
182  void delete_selection() override;
183 
184  void handle_mouse_selection(point mouse, const bool start_selection);
185 
186 private:
187  /** The history text for this widget. */
189 
190  /** The maximum length of the text input. */
191  std::size_t max_input_length_;
192 
193  /**
194  * The x offset in the widget where the text starts.
195  *
196  * This value is needed to translate a location in the widget to a location
197  * in the text.
198  */
199  unsigned text_x_offset_;
200 
201  /**
202  * The y offset in the widget where the text starts.
203  *
204  * Needed to determine whether a click is on the text.
205  */
206  unsigned text_y_offset_;
207 
208  /**
209  * The height of the text itself.
210  *
211  * Needed to determine whether a click is on the text.
212  */
213  unsigned text_height_;
214 
215  /** Updates text_x_offset_ and text_y_offset_. */
216  void update_offsets();
217 
218  /** Is the mouse in dragging mode, this affects selection in mouse move */
219  bool dragging_;
220 
221  /** Helper text to display (such as "Search") if the text box is empty. */
222  std::string hint_text_;
223 
224  /** Image (such as a magnifying glass) that accompanies the help text. */
225  std::string hint_image_;
226 
227  /** Line number of text */
228  unsigned line_num_;
229 
230  /** utility function to calculate and set line_num_ from offset */
232  unsigned get_line_num_from_offset(unsigned offset);
233 
234  /** Utility function to calculate the offset of the end of the line
235  */
236  unsigned get_line_end_offset(unsigned line_no);
237  /** Utility function to calculate the offset of the end of the line
238  */
239  unsigned get_line_start_offset(unsigned line_no);
240 
241  /** Update layout. To be called when text size changes */
242  void update_layout() {
243  set_label(get_value());
245  }
246 
247 
248  /**
249  * Inherited from text_box_base.
250  *
251  * Unmodified Handled.
252  * Control Ignored.
253  * Shift Ignored.
254  * Alt Ignored.
255  */
256  void handle_key_up_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
257 
258  /**
259  * Inherited from text_box_base.
260  *
261  * Unmodified Handled.
262  * Control Ignored.
263  * Shift Ignored.
264  * Alt Ignored.
265  */
266  void handle_key_down_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
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_left_arrow(SDL_Keymod modifier, bool& handled) override
277  {
278  text_box_base::handle_key_left_arrow(modifier, handled);
279  update_layout();
280  }
281 
282  /**
283  * Inherited from text_box_base.
284  *
285  * Unmodified Handled.
286  * Control Ignored.
287  * Shift Ignored.
288  * Alt Ignored.
289  */
290  void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) override
291  {
292  text_box_base::handle_key_right_arrow(modifier, handled);
293  update_layout();
294  }
295 
296  /**
297  * Goes one item up in the history.
298  *
299  * @returns True if there's a history, false otherwise.
300  */
301  bool history_up();
302 
303  /**
304  * Goes one item down in the history.
305  *
306  * @returns True if there's a history, false otherwise.
307  */
308  bool history_down();
309 
310  /** Inherited from text_box_base. */
311  void handle_key_tab(SDL_Keymod modifier, bool& handled) override;
312 
313  /** Inherited from text_box_base. */
314  void handle_key_enter(SDL_Keymod modifier, bool& handled) override;
315 
316  /** Inherited from text_box_base. */
317  void handle_key_clear_line(SDL_Keymod modifier, bool& handled) override;
318 
319 public:
320  /** Static type getter that does not rely on the widget being constructed. */
321  static const std::string& type();
322 
323 private:
324 
325  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
326  virtual const std::string& get_control_type() const override;
327 
328  /***** ***** ***** signal handlers ***** ****** *****/
329 
331  bool& handled,
332  const point& coordinate);
333 
335  bool& handled);
336 
338  bool& handled);
339 
341  bool& handled);
342 };
343 
344 // }---------- DEFINITION ---------{
345 
347 {
348  explicit multiline_text_definition(const config& cfg);
349 
351  {
352  explicit resolution(const config& cfg);
353 
356  };
357 };
358 
359 // }---------- BUILDER -----------{
360 
361 namespace implementation
362 {
363 
365 {
366 public:
367  explicit builder_multiline_text(const config& cfg);
368 
370 
371  virtual std::unique_ptr<widget> build() const override;
372 
373  std::string history;
374 
375  std::size_t max_input_length;
376 
378  std::string hint_image;
379 
380  bool editable;
381  bool wrap;
382 };
383 
384 } // namespace implementation
385 
386 // }------------ END --------------
387 
388 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
Base class for a multiline text area.
void handle_key_down_arrow(SDL_Keymod, bool &handled) override
Inherited from text_box_base.
void paste_selection(const bool mouse) override
Inherited from text_box_base.
bool dragging_
Is the mouse in dragging mode, this affects selection in mouse move.
unsigned line_num_
Line number of text.
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.
void set_history(const std::string &id)
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.
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.
unsigned get_line_num_from_offset(unsigned offset)
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.
multiline_text(const implementation::builder_styled_widget &builder)
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 set_line_num_from_offset()
utility function to calculate and set line_num_ from offset
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 paste_selection(const bool mouse)
Pastes the current selection.
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 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.
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:38
void push(const std::string &text)
Push string into the history.
Definition: text_box.cpp:45
window * get_window()
Get the parent window.
Definition: widget.cpp:117
void invalidate_layout()
Updates the size of the window.
Definition: window.cpp:773
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)
Base class of a resolution, contains the common keys for a resolution.
Holds a 2D point.
Definition: point.hpp:25