forked from cataclysmbnteam/Cataclysm-BN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
string_input_popup.h
290 lines (277 loc) · 10.3 KB
/
string_input_popup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#pragma once
#ifndef CATA_SRC_STRING_INPUT_POPUP_H
#define CATA_SRC_STRING_INPUT_POPUP_H
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "color.h"
#include "cursesdef.h"
class input_context;
class utf8_wrapper;
struct point;
/**
* Shows a window querying the user for input.
*
* Returns the input that was entered. If the user cancels the input (e.g. by pressing Escape),
* an empty string is returned. An empty string may also be returned when the user does not enter
* any text and confirms the input (by pressing ENTER).
*
* Examples:
* \code
input = string_input_popup().title("Enter something").query();
// shows the input field in window w at coordinates (10,20) up to (30,20).
input = string_input_popup().window(w, 10, 20, 30).query();
* \endcode
*
* @param title The displayed title, describing what to enter. @ref color_tags can be used.
* @param width Width of the input area where the user input appears.
* @param input The initially display input. The user can change this.
* @param desc An optional text (e.h. help or formatting information) which is displayed
* above the input. Color tags can be used.
* @param identifier If not empty, this is used to store and retrieve previously entered
* text. All calls with the same `identifier` share this history, the history is also stored
* when saving the game (see @ref uistate).
* @param max_length The maximal length of the text the user can input. More input is simply
* ignored and the returned string is never longer than this.
* @param only_digits Whether to only allow digits in the string.
*/
class string_input_popup // NOLINT(cata-xy)
{
private:
std::string _title;
std::string _text;
std::string _description;
std::string _identifier;
std::string _session_str_entered;
nc_color _title_color = c_light_red;
nc_color _desc_color = c_green;
nc_color _string_color = c_magenta;
nc_color _cursor_color = h_light_gray;
nc_color _underscore_color = c_light_gray;
int _width = 0;
int _max_length = -1;
bool _only_digits = false;
bool _hist_use_uilist = true;
bool _ignore_custom_actions = true;
int _startx = 0;
int _starty = 0;
int _endx = 0;
int _position = -1;
int _hist_str_ind = 0;
//Counts only when @_hist_use_uilist is false
const size_t _hist_max_size = 100;
// Cache when using the default window
int w_width = 0;
int w_height = 0;
std::vector<std::string> descformatted;
std::vector<std::string> title_split;
int titlesize = 0;
bool custom_window = false;
catacurses::window w;
std::unique_ptr<input_context> ctxt_ptr;
input_context *ctxt = nullptr;
bool _canceled = false;
bool _confirmed = false;
bool _handled = false;
void create_window();
void create_context();
void show_history( utf8_wrapper &ret );
void add_to_history( const std::string &value ) const;
void update_input_history( utf8_wrapper &ret, bool up );
void draw( const utf8_wrapper &ret, const utf8_wrapper &edit, int shift ) const;
public:
string_input_popup();
~string_input_popup();
/**
* The title: short string before the actual input field.
* It's optional, default is an empty string.
*/
string_input_popup &title( const std::string &value ) {
_title = value;
return *this;
}
/**
* Set / get the text that can be modified by the user.
* Note that canceling the query makes this an empty string.
* It's optional default is an empty string.
*/
/**@{*/
string_input_popup &text( const std::string &value );
const std::string &text() const {
return _text;
}
/**@}*/
/**
* Additional help text, shown below the input box.
* It's optional, default is an empty text.
*/
string_input_popup &description( const std::string &value ) {
_description = value;
return *this;
}
/**
* An identifier to be used to store / get the input
* history. If empty (the default), no history will be
* available, otherwise the history associated with
* the identifier will be available.
* If the input is not canceled, the new input is
* added to the history.
*/
string_input_popup &identifier( const std::string &value ) {
_identifier = value;
return *this;
}
/**
* Width (in console cells) of the input field itself.
*/
string_input_popup &width( int value ) {
_width = value;
return *this;
}
/**
* Maximal amount of Unicode characters that can be
* given by the user. The default is something like 1000.
*/
string_input_popup &max_length( int value ) {
_max_length = value;
return *this;
}
/**
* If true, any non-digit input cancels the input. Default is false.
*/
string_input_popup &only_digits( bool value ) {
_only_digits = value;
return *this;
}
/**
* Make any difference only if @identifier is used.
* If true, create UiList window with query history, otherwise use arrow keys at string input to move through history.
* Default is true.
*/
string_input_popup &hist_use_uilist( bool value ) {
_hist_use_uilist = value;
return *this;
}
/**
* If true and the custom input context returns an input action, the
* action is not handled at all and left to be handled by the caller.
* Otherwise the action is always handled as an input event to the popup.
* The caller can use @ref handled to check whether the last input is handled.
*/
string_input_popup &ignore_custom_actions( const bool value ) {
_ignore_custom_actions = value;
return *this;
}
/**
* Set the window area where to display the input text. If this is set,
* the class will not create a separate window and *only* the editable
* text will be printed at the given part of the given window.
* Integer parameters define the area (one line) where the editable
* text is printed.
*
* This method only has effect before the default window is initialized.
* After that calls to this method are just ignored.
*/
string_input_popup &window( const catacurses::window &w, point start, int endx );
/**
* Set / get the input context that is used to gather user input.
* The class will create its own context if none is set here.
*/
/**@{*/
string_input_popup &context( input_context &ctxt );
input_context &context() const {
return *ctxt;
}
/**
* Set / get the foreground color of the title.
* Optional, default value is c_light_red.
*/
string_input_popup &title_color( const nc_color &color ) {
_title_color = color;
return *this;
}
/**
* Set / get the foreground color of the description.
* Optional, default value is c_green.
*/
string_input_popup &desc_color( const nc_color &color ) {
_desc_color = color;
return *this;
}
/**
* Set / get the foreground color of the input string.
* Optional, default value is c_magenta.
*/
string_input_popup &string_color( const nc_color &color ) {
_string_color = color;
return *this;
}
/**
* Set / get the foreground color of the caret.
* Optional, default value is h_light_gray.
*/
string_input_popup &cursor_color( const nc_color &color ) {
_cursor_color = color;
return *this;
}
/**
* Set / get the foreground color of the dashed line.
* Optional, default value is c_light_gray.
*/
string_input_popup &underscore_color( const nc_color &color ) {
_underscore_color = color;
return *this;
}
/**@}*/
/**
* Draws the input box, waits for input (if \p loop is true).
* @return @ref text()
*/
/**@{*/
void query( bool loop = true, bool draw_only = false );
int query_int( bool loop = true, bool draw_only = false );
int64_t query_int64_t( bool loop = true, bool draw_only = false );
const std::string &query_string( bool loop = true, bool draw_only = false );
/**@}*/
/**
* Whether the input box was canceled via the ESCAPE key (or similar)
* If the input was finished via the ENTER key (or similar), this will
* return `false`.
*/
bool canceled() const {
return _canceled;
}
/**
* Returns true if query was finished via the ENTER key.
*/
bool confirmed() const {
return _confirmed;
}
/**
* Returns false if the last input was unhandled. Useful to avoid handling
* input already handled by the popup itself.
*/
bool handled() const {
return _handled;
}
/**
* Edit values in place. This combines: calls to @ref text to set the
* current value, @ref query to get user input and setting the
* value back into the parameter object (when the popup was not
* canceled). Canceling the popup keeps the value unmodified.
*/
/**@{*/
void edit( std::string &value );
// Acceptable to use long as part of overload set
// NOLINTNEXTLINE(cata-no-long)
void edit( long &value );
void edit( int &value );
/**@}*/
std::map<long, std::function<bool()>> callbacks;
};
#endif // CATA_SRC_STRING_INPUT_POPUP_H