The Battle for Wesnoth  1.19.4+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 private:
147  /** Inherited from text_box_base. */
148  void paste_selection(const bool mouse) override
149  {
151  update_layout();
152  }
153 
154  /** Inherited from text_box_base. */
155  void delete_char(const bool before_cursor) override;
156 
157  /** Inherited from text_box_base. */
158  void delete_selection() override;
159 
160  void handle_mouse_selection(point mouse, const bool start_selection);
161 
162 private:
163  /** The history text for this widget. */
165 
166  /** The maximum length of the text input. */
167  std::size_t max_input_length_;
168 
169  /**
170  * The x offset in the widget where the text starts.
171  *
172  * This value is needed to translate a location in the widget to a location
173  * in the text.
174  */
175  unsigned text_x_offset_;
176 
177  /**
178  * The y offset in the widget where the text starts.
179  *
180  * Needed to determine whether a click is on the text.
181  */
182  unsigned text_y_offset_;
183 
184  /**
185  * The height of the text itself.
186  *
187  * Needed to determine whether a click is on the text.
188  */
189  unsigned text_height_;
190 
191  /** Updates text_x_offset_ and text_y_offset_. */
192  void update_offsets();
193 
194  /** Is the mouse in dragging mode, this affects selection in mouse move */
195  bool dragging_;
196 
197  /** Helper text to display (such as "Search") if the text box is empty. */
198  std::string hint_text_;
199 
200  /** Image (such as a magnifying glass) that accompanies the help text. */
201  std::string hint_image_;
202 
203  /**
204  * Utility function to calculate the offset of the end of the line
205  */
206  unsigned get_line_end_offset(unsigned line_no);
207 
208  /**
209  * Utility function to calculate the offset of the end of the line
210  */
211  unsigned get_line_start_offset(unsigned line_no);
212 
213  /** Update layout. To be called when text size changes */
214  void update_layout() {
215  set_label(get_value());
217  }
218 
219 
220  /**
221  * Inherited from text_box_base.
222  *
223  * Unmodified Handled.
224  * Control Ignored.
225  * Shift Ignored.
226  * Alt Ignored.
227  */
228  void handle_key_up_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
229 
230  /**
231  * Inherited from text_box_base.
232  *
233  * Unmodified Handled.
234  * Control Ignored.
235  * Shift Ignored.
236  * Alt Ignored.
237  */
238  void handle_key_down_arrow(SDL_Keymod /*modifier*/, bool& handled) override;
239 
240  /**
241  * Inherited from text_box_base.
242  *
243  * Unmodified Handled.
244  * Control Ignored.
245  * Shift Ignored.
246  * Alt Ignored.
247  */
248  void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) override
249  {
250  text_box_base::handle_key_left_arrow(modifier, handled);
251  update_layout();
252  }
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_right_arrow(SDL_Keymod modifier, bool& handled) override
263  {
264  text_box_base::handle_key_right_arrow(modifier, handled);
265  update_layout();
266  }
267 
268  /**
269  * Goes one item up in the history.
270  *
271  * @returns True if there's a history, false otherwise.
272  */
273  bool history_up();
274 
275  /**
276  * Goes one item down in the history.
277  *
278  * @returns True if there's a history, false otherwise.
279  */
280  bool history_down();
281 
282  /** Inherited from text_box_base. */
283  void handle_key_tab(SDL_Keymod modifier, bool& handled) override;
284 
285  /** Inherited from text_box_base. */
286  void handle_key_enter(SDL_Keymod modifier, bool& handled) override;
287 
288  /** Inherited from text_box_base. */
289  void handle_key_clear_line(SDL_Keymod modifier, bool& handled) override;
290 
291 public:
292  /** Static type getter that does not rely on the widget being constructed. */
293  static const std::string& type();
294 
295 private:
296 
297  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
298  virtual const std::string& get_control_type() const override;
299 
300  /***** ***** ***** signal handlers ***** ****** *****/
301 
303  bool& handled,
304  const point& coordinate);
305 
307  bool& handled);
308 
310  bool& handled);
311 
313  bool& handled);
314 };
315 
316 // }---------- DEFINITION ---------{
317 
319 {
320  explicit multiline_text_definition(const config& cfg);
321 
323  {
324  explicit resolution(const config& cfg);
325 
328  };
329 };
330 
331 // }---------- BUILDER -----------{
332 
333 namespace implementation
334 {
335 
337 {
338 public:
339  explicit builder_multiline_text(const config& cfg);
340 
342 
343  virtual std::unique_ptr<widget> build() const override;
344 
345  std::string history;
346 
347  std::size_t max_input_length;
348 
350  std::string hint_image;
351 
352  bool editable;
353  bool wrap;
354 };
355 
356 } // namespace implementation
357 
358 // }------------ END --------------
359 
360 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:163
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 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.
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 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.
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: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)
Holds a 2D point.
Definition: point.hpp:25