construct_dialog.hpp

Go to the documentation of this file.
00001 /* $Id: construct_dialog.hpp 24817 2008-03-19 15:23:47Z brunowolff $ */
00002 /*
00003    Copyright (C) 2006 - 2008 by Patrick Parker <patrick_x99@hotmail.com>
00004    wesnoth widget Copyright (C) 2003-5 by David White <dave@whitevine.net>
00005    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License version 2
00009    or at your option any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
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     //surface surface() const { return surf_; }
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     //forbidden operations
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         //use get_frame().get_layout() to check frame dimensions
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     //Static members
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     //Constructor & destructor
00194     //dialog - throws button::error() if standard buttons fail to initialize
00195     //         throws utils::invalid_utf8_exception() if message is invalid
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     //Adding components - the dialog will manage the memory of
00204     //these widgets, therefore do not attempt to reference its
00205     //widgets after destroying it
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     //add_pane - preview panes are not currently memory managed
00213     //(for backwards compatibility)
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     //Specific preparations
00229     //layout - determines dialog measurements based on all components
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     //Launching the dialog
00237     //show - the return value of this method should be the same as result()
00238     int show(int xloc, int yloc);
00239     int show();
00240 
00241     //Results
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     //action - invoked at the end of the dialog-processing loop
00254     virtual void action(dialog_process_info &dp_info);
00255     //refresh - forces the display to refresh
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     //process - execute a single dialog processing loop and return the result
00267     int process(dialog_process_info &info);
00268 
00269     //Members
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; // 3 times the 0.1sec human reflex-arc time
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 } //end namespace gui
00308 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs