This repository has been archived by the owner on Sep 4, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
construct_dialog.hpp
333 lines (291 loc) · 10.4 KB
/
construct_dialog.hpp
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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/* $Id: construct_dialog.hpp 48153 2011-01-01 15:57:50Z mordante $ */
/*
Copyright (C) 2006 - 2011 by Patrick Parker <patrick_x99@hotmail.com>
wesnoth widget Copyright (C) 2003-5 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef CONSTRUCT_DIALOG_H_INCLUDED
#define CONSTRUCT_DIALOG_H_INCLUDED
#include "show_dialog.hpp"
#include "widgets/label.hpp"
#include "widgets/textbox.hpp"
#include "key.hpp"
namespace gui {
struct dialog_process_info
{
public:
dialog_process_info() :
key(),
left_button(true),
right_button(true),
key_down(true),
first_time(true),
double_clicked(false),
new_left_button(false),
new_right_button(false),
new_key_down(false),
selection(-1),
clear_buttons_(false)
{}
void clear_buttons() {
clear_buttons_ = true;
}
void cycle() {
if(clear_buttons_) {
left_button = true;
right_button = true;
key_down = true;
clear_buttons_ = false;
} else {
left_button = new_left_button;
right_button = new_right_button;
key_down = new_key_down;
}
}
CKey key;
bool left_button, right_button, key_down, first_time, double_clicked;
bool new_left_button, new_right_button, new_key_down;
int selection;
private:
bool clear_buttons_;
};
class dialog_image : public widget {
public:
dialog_image(label *const caption, CVideo &video, surface img) : widget(video, false),
surf_(img), caption_(caption)
{
if(!img.null()) {
set_measurements(img->w, img->h);
}
}
~dialog_image() { delete caption_; }
//surface surface() const { return surf_; }
label *caption() const { return caption_; }
void draw_contents();
handler_vector handler_members() {
handler_vector h;
if(caption_) h.push_back(caption_);
return h;
}
private:
surface surf_;
label *caption_;
};
class dialog_textbox : public textbox {
public:
dialog_textbox(label *const label_widget, CVideo &video, int width, const std::string& text="", bool editable=true, size_t max_size = 256, double alpha = 0.4, double alpha_focus = 0.2)
: textbox(video, width, text, editable, max_size, alpha, alpha_focus, false),
label_(label_widget)
{}
virtual ~dialog_textbox();
label *get_label() const { return label_; }
handler_vector handler_members() {
handler_vector h = textbox::handler_members();
if(label_) h.push_back(label_);
return h;
}
private:
//forbidden operations
dialog_textbox(const dialog_textbox&);
void operator=(const dialog_textbox&);
label *label_;
};
class dialog;
class filter_textbox : public gui::dialog_textbox {
public:
filter_textbox(CVideo& video, const std::string& header,
const std::vector<std::string>& items,
const std::vector<std::string>& items_to_filter, size_t header_row,
dialog& dialog, int width = 250) :
dialog_textbox(new label(video, header), video, width),
items_(items),
items_to_filter_(items_to_filter),
filtered_items_(),
index_map_(),
last_words(1, ""), // dummy word to trigger an update
header_row_(header_row),
dialog_(dialog)
{
set_text("");
}
// current menu selection is based on a possibly filtered view,
// and thus may differ from the original, unfiltered index
int get_index(int selection) const;
void delete_item(int selection);
private:
std::vector<std::string> items_, items_to_filter_, filtered_items_;
std::vector<int> index_map_;
std::vector<std::string> last_words;
size_t header_row_;
gui::dialog& dialog_;
virtual void handle_text_changed(const wide_string& text);
};
class dialog_button : public button {
public:
dialog_button(CVideo& video, const std::string& label, TYPE type=TYPE_PRESS,
int simple_result=CONTINUE_DIALOG, dialog_button_action *handler=NULL)
: button(video,label,type,"",DEFAULT_SPACE,false), simple_result_(simple_result),
parent_(NULL), handler_(handler)
{}
void set_parent(class dialog *parent) {
parent_ = parent;
}
bool is_option() const {
return (type_ == TYPE_CHECK);
}
virtual int action(dialog_process_info &info);
protected:
class dialog *dialog() const { return parent_; }
const int simple_result_;
private:
class dialog *parent_;
dialog_button_action *handler_;
};
class standard_dialog_button : public dialog_button {
public:
standard_dialog_button(CVideo& video, const std::string& label, const int index, const bool is_last)
: dialog_button(video,label,TYPE_PRESS,index), is_last_(is_last)
{}
int action(dialog_process_info &info);
private:
const bool is_last_;
};
class dialog {
public:
enum BUTTON_LOCATION { BUTTON_STANDARD, BUTTON_EXTRA, BUTTON_EXTRA_LEFT, BUTTON_CHECKBOX, BUTTON_CHECKBOX_LEFT, BUTTON_HELP };
struct dimension_measurements {
dimension_measurements();
int x, y;
SDL_Rect interior, message, textbox;
unsigned int menu_width;
#ifdef __PLAYBOOK__
std::map<preview_pane *, SDL_Rect > panes;
#else
std::map<preview_pane *const, SDL_Rect > panes;
#endif
int label_x, label_y;
int menu_x, menu_y, menu_height;
int image_x, image_y, caption_x, caption_y;
#ifdef __PLAYBOOK__
std::map<dialog_button *, std::pair<int,int> > buttons;
#else
std::map<dialog_button *const, std::pair<int,int> > buttons;
#endif
//use get_frame().get_layout() to check frame dimensions
};
typedef dialog_frame::style style;
private:
typedef std::vector<preview_pane *>::iterator pp_iterator;
typedef std::vector<preview_pane *>::const_iterator pp_const_iterator;
typedef std::vector<dialog_button *>::iterator button_iterator;
typedef std::vector<dialog_button *>::const_iterator button_const_iterator;
typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::iterator button_pool_iterator;
typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::const_iterator button_pool_const_iterator;
public:
//Static members
static const style& default_style;
static const style& message_style;
static const style hotkeys_style;
static const int message_font_size;
static const int caption_font_size;
static const int max_menu_width;
static const size_t left_padding;
static const size_t right_padding;
static const size_t image_h_pad;
static const size_t top_padding;
static const size_t bottom_padding;
//Constructor & destructor
//dialog - throws button::error() if standard buttons fail to initialize
// throws utils::invalid_utf8_exception() if message is invalid
dialog(display &disp,
const std::string& title="",
const std::string& message="",
const DIALOG_TYPE type=MESSAGE,
const style& dialog_style=default_style);
virtual ~dialog();
//Adding components - the dialog will manage the memory of
//these widgets, therefore do not attempt to reference its
//widgets after destroying it
void set_image(dialog_image *const img) { delete image_; image_ = img; }
void set_image(surface surf, const std::string &caption="");
void set_menu(menu *const m) { if(menu_ != empty_menu) delete menu_; menu_ = m; }
void set_menu(const std::vector<std::string> & menu_items, menu::sorter* sorter=NULL);
void set_menu_items(const std::vector<std::string> &menu_items);
//add_pane - preview panes are not currently memory managed
//(for backwards compatibility)
void add_pane(preview_pane *const pp) { preview_panes_.push_back(pp); }
void set_panes(std::vector<preview_pane*> panes) { preview_panes_ = panes; }
void set_textbox(dialog_textbox *const box) {
delete text_widget_;
text_widget_ = box;
}
void set_textbox(const std::string& text_widget_label="",
const std::string &text_widget_text="",
const int text_widget_max_chars = 256,
const unsigned int text_box_width = font::relative_size(350));
void add_button(dialog_button *const btn, BUTTON_LOCATION loc);
void add_button(dialog_button_info btn_info, BUTTON_LOCATION loc=BUTTON_EXTRA);
void add_option(const std::string& label, bool checked=false, BUTTON_LOCATION loc=BUTTON_CHECKBOX);
//Specific preparations
//layout - determines dialog measurements based on all components
virtual dimension_measurements layout(int xloc=-1, int yloc=-1);
void set_layout(dimension_measurements &new_dim);
dimension_measurements get_layout() const { return dim_; }
dialog_frame& get_frame();
void set_basic_behavior(DIALOG_TYPE type) { type_ = type; }
//Launching the dialog
//show - the return value of this method should be the same as result()
int show(int xloc, int yloc);
int show();
//Results
int result() const { return result_; }
menu &get_menu();
bool done() const { return (result_ != CONTINUE_DIALOG); }
std::string textbox_text() const { return text_widget_->text();}
dialog_textbox& get_textbox() const { return *text_widget_; }
bool option_checked(unsigned int option_index=0);
display& get_display() { return disp_; }
protected:
void set_result(const int result) { result_ = result; }
//action - invoked at the end of the dialog-processing loop
virtual void action(dialog_process_info &dp_info);
//refresh - forces the display to refresh
void refresh();
label& get_message() const { return *message_; }
private:
void clear_background();
void draw_frame();
void update_widget_positions();
void draw_contents();
//process - execute a single dialog processing loop and return the result
int process(dialog_process_info &info);
//Members
display &disp_;
dialog_image *image_;
std::string title_;
const style& style_;
label *title_widget_, *message_;
DIALOG_TYPE type_;
gui::menu *menu_;
std::vector<preview_pane*> preview_panes_;
std::vector< std::pair<dialog_button*,BUTTON_LOCATION> > button_pool_;
std::vector<dialog_button*> standard_buttons_;
std::vector<dialog_button*> extra_buttons_;
std::vector<button*> frame_buttons_;
std::string topic_;
dialog_button *help_button_;
dialog_textbox *text_widget_;
dialog_frame *frame_;
dimension_measurements dim_;
int result_;
};
typedef Uint32 msecs;
} //end namespace gui
#endif