00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef CONSTRUCT_DIALOG_H_INCLUDED
00017 #define CONSTRUCT_DIALOG_H_INCLUDED
00018
00019 #include "show_dialog.hpp"
00020
00021 #include "widgets/label.hpp"
00022 #include "widgets/textbox.hpp"
00023 #include "widgets/button.hpp"
00024 #include "widgets/menu.hpp"
00025 #include "key.hpp"
00026 #include "sdl_utils.hpp"
00027
00028 namespace gui {
00029
00030 struct dialog_process_info
00031 {
00032 public:
00033 dialog_process_info() :
00034 key(),
00035 left_button(true),
00036 right_button(true),
00037 key_down(true),
00038 first_time(true),
00039 double_clicked(false),
00040 new_left_button(false),
00041 new_right_button(false),
00042 new_key_down(false),
00043 selection(-1),
00044 clear_buttons_(false)
00045 {}
00046
00047 void clear_buttons() {
00048 clear_buttons_ = true;
00049 }
00050
00051 void cycle() {
00052 if(clear_buttons_) {
00053 left_button = true;
00054 right_button = true;
00055 key_down = true;
00056 clear_buttons_ = false;
00057 } else {
00058 left_button = new_left_button;
00059 right_button = new_right_button;
00060 key_down = new_key_down;
00061 }
00062 }
00063 CKey key;
00064 bool left_button, right_button, key_down, first_time, double_clicked;
00065 bool new_left_button, new_right_button, new_key_down;
00066 int selection;
00067 private:
00068 bool clear_buttons_;
00069 };
00070
00071 class dialog_image : public widget {
00072 public:
00073 dialog_image(label *const caption, CVideo &video, surface img) : widget(video, false),
00074 surf_(img), caption_(caption)
00075 {
00076 if(!img.null()) {
00077 set_measurements(img->w, img->h);
00078 }
00079 }
00080 ~dialog_image() { delete caption_; }
00081
00082
00083 label *caption() const { return caption_; }
00084 void draw_contents();
00085
00086 handler_vector handler_members() {
00087 handler_vector h;
00088 if(caption_) h.push_back(caption_);
00089 return h;
00090 }
00091 private:
00092
00093 surface surf_;
00094 label *caption_;
00095 };
00096
00097 class dialog_textbox : public textbox {
00098 public:
00099 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)
00100 : textbox(video, width, text, editable, max_size, alpha, alpha_focus, false),
00101 label_(label_widget)
00102 {}
00103 virtual ~dialog_textbox();
00104
00105 label *get_label() const { return label_; }
00106
00107 handler_vector handler_members() {
00108 handler_vector h = textbox::handler_members();
00109 if(label_) h.push_back(label_);
00110 return h;
00111 }
00112 private:
00113
00114 dialog_textbox(const dialog_textbox&);
00115 void operator=(const dialog_textbox&);
00116
00117 label *label_;
00118 };
00119
00120 class dialog_button : public button {
00121 public:
00122 dialog_button(CVideo& video, const std::string& label, TYPE type=TYPE_PRESS,
00123 int simple_result=CONTINUE_DIALOG, dialog_button_action *handler=NULL)
00124 : button(video,label,type,"",DEFAULT_SPACE,false), simple_result_(simple_result),
00125 parent_(NULL), handler_(handler)
00126 {}
00127 void set_parent(class dialog *parent) {
00128 parent_ = parent;
00129 }
00130 bool is_option() const {
00131 return (type_ == TYPE_CHECK);
00132 }
00133 virtual int action(dialog_process_info &info);
00134 protected:
00135 class dialog *dialog() const { return parent_; }
00136 const int simple_result_;
00137 private:
00138 class dialog *parent_;
00139 dialog_button_action *handler_;
00140 };
00141
00142 class standard_dialog_button : public dialog_button {
00143 public:
00144 standard_dialog_button(CVideo& video, const std::string& label, const int index, const bool is_last)
00145 : dialog_button(video,label,TYPE_PRESS,index), is_last_(is_last)
00146 {}
00147 int action(dialog_process_info &info);
00148 private:
00149 const bool is_last_;
00150 };
00151
00152
00153 class dialog {
00154 public:
00155 enum BUTTON_LOCATION { BUTTON_STANDARD, BUTTON_EXTRA, BUTTON_EXTRA_LEFT, BUTTON_CHECKBOX, BUTTON_CHECKBOX_LEFT, BUTTON_HELP };
00156 struct dimension_measurements {
00157 dimension_measurements();
00158 int x, y;
00159 SDL_Rect interior, message, textbox;
00160 unsigned int menu_width;
00161 std::map<preview_pane *const, SDL_Rect > panes;
00162 int label_x, label_y;
00163 int menu_x, menu_y, menu_height;
00164 int image_x, image_y, caption_x, caption_y;
00165 std::map<dialog_button *const, std::pair<int,int> > buttons;
00166
00167 };
00168 typedef dialog_frame::style style;
00169
00170 private:
00171 typedef std::vector<preview_pane *>::iterator pp_iterator;
00172 typedef std::vector<preview_pane *>::const_iterator pp_const_iterator;
00173 typedef std::vector<dialog_button *>::iterator button_iterator;
00174 typedef std::vector<dialog_button *>::const_iterator button_const_iterator;
00175 typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::iterator button_pool_iterator;
00176 typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::const_iterator button_pool_const_iterator;
00177
00178 public:
00179
00180
00181 static const style& default_style;
00182 static const style& message_style;
00183 static const style hotkeys_style;
00184 static const int message_font_size;
00185 static const int caption_font_size;
00186 static const int max_menu_width;
00187 static const size_t left_padding;
00188 static const size_t right_padding;
00189 static const size_t image_h_pad;
00190 static const size_t top_padding;
00191 static const size_t bottom_padding;
00192
00193
00194
00195
00196 dialog(display &disp,
00197 const std::string& title="",
00198 const std::string& message="",
00199 const DIALOG_TYPE type=MESSAGE,
00200 const style& dialog_style=default_style);
00201 virtual ~dialog();
00202
00203
00204
00205
00206 void set_image(dialog_image *const img) { delete image_; image_ = img; }
00207 void set_image(surface surf, const std::string &caption="");
00208 void set_menu(menu *const m) { if(menu_ != empty_menu) delete menu_; menu_ = m; }
00209 void set_menu(const std::vector<std::string> & menu_items, menu::sorter* sorter=NULL);
00210 void set_menu_items(const std::vector<std::string> &menu_items);
00211
00212
00213
00214 void add_pane(preview_pane *const pp) { preview_panes_.push_back(pp); }
00215 void set_panes(std::vector<preview_pane*> panes) { preview_panes_ = panes; }
00216 void set_textbox(dialog_textbox *const box) {
00217 delete text_widget_;
00218 text_widget_ = box;
00219 }
00220 void set_textbox(const std::string& text_widget_label="",
00221 const std::string &text_widget_text="",
00222 const int text_widget_max_chars = 256,
00223 const unsigned int text_box_width = font::relative_size(350));
00224 void add_button(dialog_button *const btn, BUTTON_LOCATION loc);
00225 void add_button(dialog_button_info btn_info, BUTTON_LOCATION loc=BUTTON_EXTRA);
00226 void add_option(const std::string& label, bool checked=false, BUTTON_LOCATION loc=BUTTON_CHECKBOX);
00227
00228
00229
00230 virtual dimension_measurements layout(int xloc=-1, int yloc=-1);
00231 void set_layout(dimension_measurements &new_dim);
00232 dimension_measurements get_layout() const { return dim_; }
00233 dialog_frame& get_frame();
00234 void set_basic_behavior(DIALOG_TYPE type) { type_ = type; }
00235
00236
00237
00238 int show(int xloc, int yloc);
00239 int show();
00240
00241
00242 int result() const { return result_; }
00243 menu &get_menu();
00244 bool done() const { return (result_ != CONTINUE_DIALOG); }
00245 const std::string textbox_text() const { return text_widget_->text();}
00246 dialog_textbox& get_textbox() const { return *text_widget_; }
00247 bool option_checked(unsigned int option_index=0);
00248 display& get_display() { return disp_; }
00249
00250 protected:
00251 void set_result(const int result) { result_ = result; }
00252
00253
00254 virtual void action(dialog_process_info &dp_info);
00255
00256 void refresh();
00257
00258 label& get_message() const { return *message_; }
00259
00260 private:
00261 void clear_background();
00262 void draw_frame();
00263 void update_widget_positions();
00264 void draw_contents();
00265
00266
00267 int process(dialog_process_info &info);
00268
00269
00270 display &disp_;
00271 dialog_image *image_;
00272 std::string title_;
00273 const style& style_;
00274 label *title_widget_, *message_;
00275 DIALOG_TYPE type_;
00276 gui::menu *menu_;
00277 std::vector<preview_pane*> preview_panes_;
00278 std::vector< std::pair<dialog_button*,BUTTON_LOCATION> > button_pool_;
00279 std::vector<dialog_button*> standard_buttons_;
00280 std::vector<dialog_button*> extra_buttons_;
00281 std::vector<button*> frame_buttons_;
00282 std::string topic_;
00283 dialog_button *help_button_;
00284 dialog_textbox *text_widget_;
00285 dialog_frame *frame_;
00286 dimension_measurements dim_;
00287 int result_;
00288 };
00289
00290 typedef Uint32 msecs;
00291 const msecs three_blinks = 300;
00292
00293 class message_dialog : public gui::dialog
00294 {
00295 public:
00296 message_dialog(display &disp, const std::string& title="", const std::string& message="", const gui::DIALOG_TYPE type=gui::MESSAGE)
00297 : dialog(disp, title, message, type, message_style), prevent_misclick_until_(0)
00298 {}
00299 ~message_dialog();
00300 int show(msecs minimum_lifetime = three_blinks);
00301 protected:
00302 void action(gui::dialog_process_info &dp_info);
00303 private:
00304 msecs prevent_misclick_until_;
00305 };
00306
00307 }
00308 #endif