construct_dialog.hpp

Go to the documentation of this file.
00001 /* $Id: construct_dialog.hpp 52964 2012-02-07 19:05:59Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2006 - 2012 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 as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY.
00013 
00014    See the COPYING file for more details.
00015 */
00016 
00017 #ifndef CONSTRUCT_DIALOG_H_INCLUDED
00018 #define CONSTRUCT_DIALOG_H_INCLUDED
00019 
00020 #include "show_dialog.hpp"
00021 
00022 #include "widgets/label.hpp"
00023 #include "widgets/textbox.hpp"
00024 #include "key.hpp"
00025 
00026 namespace gui {
00027 
00028 struct dialog_process_info
00029 {
00030 public:
00031     dialog_process_info() :
00032         key(),
00033         left_button(true),
00034         right_button(true),
00035         key_down(true),
00036         first_time(true),
00037         double_clicked(false),
00038         new_left_button(false),
00039         new_right_button(false),
00040         new_key_down(false),
00041         selection(-1),
00042         clear_buttons_(false)
00043     {}
00044 
00045     void clear_buttons() {
00046         clear_buttons_ = true;
00047     }
00048 
00049     void cycle() {
00050         if(clear_buttons_) {
00051             left_button = true;
00052             right_button = true;
00053             key_down = true;
00054             clear_buttons_ = false;
00055         } else {
00056             left_button = new_left_button;
00057             right_button = new_right_button;
00058             key_down = new_key_down;
00059         }
00060     }
00061     CKey key;
00062     bool left_button, right_button, key_down, first_time, double_clicked;
00063     bool new_left_button, new_right_button, new_key_down;
00064     int selection;
00065 private:
00066     bool clear_buttons_;
00067 };
00068 
00069 class dialog_image : public widget {
00070 public:
00071     dialog_image(label *const caption, CVideo &video, surface img) : widget(video, false),
00072       surf_(img), caption_(caption)
00073     {
00074         if(!img.null()) {
00075             set_measurements(img->w, img->h);
00076         }
00077     }
00078     ~dialog_image() { delete caption_; }
00079 
00080     //surface surface() const { return surf_; }
00081     label *caption() const { return caption_; }
00082     void draw_contents();
00083 
00084     handler_vector handler_members() {
00085         handler_vector h;
00086         if(caption_) h.push_back(caption_);
00087         return h;
00088     }
00089 private:
00090 
00091     surface surf_;
00092     label *caption_;
00093 };
00094 
00095 class dialog_textbox : public textbox {
00096 public:
00097     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)
00098         : textbox(video, width, text, editable, max_size, alpha, alpha_focus, false),
00099         label_(label_widget)
00100     {}
00101     virtual ~dialog_textbox();
00102 
00103     label *get_label() const { return label_; }
00104 
00105     handler_vector handler_members() {
00106         handler_vector h = textbox::handler_members();
00107         if(label_) h.push_back(label_);
00108         return h;
00109     }
00110 private:
00111     //forbidden operations
00112     dialog_textbox(const dialog_textbox&);
00113     void operator=(const dialog_textbox&);
00114 
00115     label *label_;
00116 };
00117 
00118 class dialog;
00119 
00120 class filter_textbox : public gui::dialog_textbox {
00121 public:
00122     filter_textbox(CVideo& video, const std::string& header,
00123             const std::vector<std::string>& items,
00124             const std::vector<std::string>& items_to_filter, size_t header_row,
00125             dialog& dialog, int width = 250) :
00126         dialog_textbox(new label(video, header), video, width),
00127         items_(items),
00128         items_to_filter_(items_to_filter),
00129         filtered_items_(),
00130         index_map_(),
00131         last_words(1, ""), // dummy word to trigger an update
00132         header_row_(header_row),
00133         dialog_(dialog)
00134     {
00135         set_text("");
00136     }
00137 
00138     // current menu selection is based on a possibly filtered view,
00139     // and thus may differ from the original, unfiltered index
00140     int get_index(int selection) const;
00141     void delete_item(int selection);
00142 
00143 private:
00144     std::vector<std::string> items_, items_to_filter_, filtered_items_;
00145     std::vector<int> index_map_;
00146     std::vector<std::string> last_words;
00147     size_t header_row_;
00148     gui::dialog& dialog_;
00149     virtual void handle_text_changed(const wide_string& text);
00150 };
00151 
00152 class dialog_button : public button {
00153 public:
00154     dialog_button(CVideo& video, const std::string& label, TYPE type=TYPE_PRESS,
00155         int simple_result=CONTINUE_DIALOG, dialog_button_action *handler=NULL)
00156         : button(video,label,type,"",DEFAULT_SPACE,false), simple_result_(simple_result),
00157         parent_(NULL), handler_(handler)
00158     {}
00159     void set_parent(class dialog *parent) {
00160         parent_ = parent;
00161     }
00162     bool is_option() const {
00163         return (type_ == TYPE_CHECK);
00164     }
00165     virtual int action(dialog_process_info &info);
00166 protected:
00167     class dialog *dialog() const { return parent_; }
00168     const int simple_result_;
00169 private:
00170     class dialog *parent_;
00171     dialog_button_action *handler_;
00172 };
00173 
00174 class standard_dialog_button : public dialog_button {
00175 public:
00176     standard_dialog_button(CVideo& video, const std::string& label, const int index, const bool is_last)
00177         : dialog_button(video,label,TYPE_PRESS,index), is_last_(is_last)
00178     {}
00179     int action(dialog_process_info &info);
00180 private:
00181     const bool is_last_;
00182 };
00183 
00184 
00185 class dialog {
00186 public:
00187     enum BUTTON_LOCATION { BUTTON_STANDARD, BUTTON_EXTRA, BUTTON_EXTRA_LEFT, BUTTON_CHECKBOX, BUTTON_CHECKBOX_LEFT, BUTTON_HELP };
00188     struct dimension_measurements {
00189         dimension_measurements();
00190         int x, y;
00191         SDL_Rect interior, message, textbox;
00192         unsigned int menu_width;
00193         std::map<preview_pane *const, SDL_Rect > panes;
00194         int label_x, label_y;
00195         int menu_x, menu_y, menu_height;
00196         int image_x, image_y, caption_x, caption_y;
00197         std::map<dialog_button *const, std::pair<int,int> > buttons;
00198         //use get_frame().get_layout() to check frame dimensions
00199     };
00200     typedef dialog_frame::style style;
00201 
00202 private:
00203     typedef std::vector<preview_pane *>::iterator pp_iterator;
00204     typedef std::vector<preview_pane *>::const_iterator pp_const_iterator;
00205     typedef std::vector<dialog_button *>::iterator button_iterator;
00206     typedef std::vector<dialog_button *>::const_iterator button_const_iterator;
00207     typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::iterator button_pool_iterator;
00208     typedef std::vector< std::pair<dialog_button *, BUTTON_LOCATION> >::const_iterator button_pool_const_iterator;
00209 
00210 public:
00211 
00212     //Static members
00213     static const style& default_style;
00214     static const style& message_style;
00215     static const style hotkeys_style;
00216     static const int message_font_size;
00217     static const int caption_font_size;
00218     static const int max_menu_width;
00219     static const size_t left_padding;
00220     static const size_t right_padding;
00221     static const size_t image_h_pad;
00222     static const size_t top_padding;
00223     static const size_t bottom_padding;
00224 
00225     //Constructor & destructor
00226     //dialog - throws button::error() if standard buttons fail to initialize
00227     //         throws utils::invalid_utf8_exception() if message is invalid
00228     dialog(display &disp,
00229            const std::string& title="",
00230            const std::string& message="",
00231            const DIALOG_TYPE type=MESSAGE,
00232            const style& dialog_style=default_style);
00233     virtual ~dialog();
00234 
00235     //Adding components - the dialog will manage the memory of
00236     //these widgets, therefore do not attempt to reference its
00237     //widgets after destroying it
00238     void set_image(dialog_image *const img) { delete image_; image_ = img; }
00239     void set_image(surface surf, const std::string &caption="");
00240     void set_menu(menu *const m) { if(menu_ != empty_menu) delete menu_; menu_ = m; }
00241     void set_menu(const std::vector<std::string> & menu_items, menu::sorter* sorter=NULL);
00242     void set_menu_items(const std::vector<std::string> &menu_items);
00243 
00244     //add_pane - preview panes are not currently memory managed
00245     //(for backwards compatibility)
00246     void add_pane(preview_pane *const pp) { preview_panes_.push_back(pp); }
00247     void set_panes(std::vector<preview_pane*> panes) { preview_panes_ = panes; }
00248     void set_textbox(dialog_textbox *const box) {
00249         delete text_widget_;
00250         text_widget_ = box;
00251     }
00252     void set_textbox(const std::string& text_widget_label="",
00253                 const std::string &text_widget_text="",
00254                 const int text_widget_max_chars = 256,
00255                 const unsigned int text_box_width = font::relative_size(350));
00256     void add_button(dialog_button *const btn, BUTTON_LOCATION loc);
00257     void add_button(dialog_button_info btn_info, BUTTON_LOCATION loc=BUTTON_EXTRA);
00258     void add_option(const std::string& label, bool checked=false, BUTTON_LOCATION loc=BUTTON_CHECKBOX, const std::string& help_string = "");
00259 
00260     //Specific preparations
00261     //layout - determines dialog measurements based on all components
00262     virtual dimension_measurements layout(int xloc=-1, int yloc=-1);
00263     void set_layout(dimension_measurements &new_dim);
00264     dimension_measurements get_layout() const { return dim_; }
00265     dialog_frame& get_frame();
00266     void set_basic_behavior(DIALOG_TYPE type) { type_ = type; }
00267 
00268     //Launching the dialog
00269     //show - the return value of this method should be the same as result()
00270     int show(int xloc, int yloc);
00271     int show();
00272 
00273     //Results
00274     int result() const { return result_; }
00275     menu &get_menu();
00276     bool done() const { return (result_ != CONTINUE_DIALOG); }
00277     std::string textbox_text() const { return text_widget_->text();}
00278     dialog_textbox& get_textbox() const { return *text_widget_; }
00279     bool option_checked(unsigned int option_index=0);
00280     display& get_display() { return disp_; }
00281 
00282 protected:
00283     void set_result(const int result) { result_ = result; }
00284 
00285     //action - invoked at the end of the dialog-processing loop
00286     virtual void action(dialog_process_info &dp_info);
00287     //refresh - forces the display to refresh
00288     void refresh();
00289 
00290     label& get_message() const { return *message_; }
00291 
00292 private:
00293     void clear_background();
00294     void draw_frame();
00295     void update_widget_positions();
00296     void draw_contents();
00297 
00298     //process - execute a single dialog processing loop and return the result
00299     int process(dialog_process_info &info);
00300 
00301     //Members
00302     display &disp_;
00303     dialog_image *image_;
00304     std::string title_;
00305     const style& style_;
00306     label *title_widget_, *message_;
00307     DIALOG_TYPE type_;
00308     gui::menu *menu_;
00309     std::vector<preview_pane*> preview_panes_;
00310     std::vector< std::pair<dialog_button*,BUTTON_LOCATION> > button_pool_;
00311     std::vector<dialog_button*> standard_buttons_;
00312     std::vector<dialog_button*> extra_buttons_;
00313     std::vector<button*> frame_buttons_;
00314     std::string topic_;
00315     dialog_button *help_button_;
00316     dialog_textbox *text_widget_;
00317     dialog_frame *frame_;
00318     dimension_measurements dim_;
00319     int result_;
00320 };
00321 
00322 typedef Uint32 msecs;
00323 
00324 } //end namespace gui
00325 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:33 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs