widgets/menu.hpp

Go to the documentation of this file.
00001 /* $Id: menu.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (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 WIDGET_MENU_HPP_INCLUDED
00017 #define WIDGET_MENU_HPP_INCLUDED
00018 
00019 #include <set>
00020 
00021 #include "scrollarea.hpp"
00022 
00023 namespace image{
00024     class locator;
00025 }
00026 
00027 namespace gui {
00028 
00029 class menu;
00030 extern menu *empty_menu;
00031 
00032 class menu : public scrollarea
00033 {
00034 public:
00035 
00036     enum ROW_TYPE { NORMAL_ROW, SELECTED_ROW, HEADING_ROW };
00037     //basic menu style
00038     class style
00039     {
00040     public:
00041         style();
00042         virtual ~style();
00043         virtual void init() {}
00044 
00045         virtual SDL_Rect item_size(const std::string& item) const;
00046         virtual void draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00047         virtual void draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00048         void scale_images(int max_width, int max_height);
00049 
00050         surface get_item_image(const image::locator &i_locator) const;
00051         size_t get_font_size() const;
00052         size_t get_cell_padding() const;
00053         size_t get_thickness() const;
00054 
00055     protected:
00056         size_t font_size_;
00057         size_t cell_padding_;
00058         size_t thickness_;  //additional cell padding for style use only
00059 
00060         int normal_rgb_, selected_rgb_, heading_rgb_;
00061         double normal_alpha_, selected_alpha_, heading_alpha_;
00062         int max_img_w_, max_img_h_;
00063     };
00064 
00065     //image-border selection style
00066     class imgsel_style : public style
00067     {
00068     public:
00069         imgsel_style(const std::string &img_base, bool has_bg,
00070                                  int normal_rgb, int selected_rgb, int heading_rgb,
00071                                  double normal_alpha, double selected_alpha, double heading_alpha);
00072         virtual ~imgsel_style();
00073 
00074         virtual SDL_Rect item_size(const std::string& item) const;
00075         virtual void draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00076         virtual void draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00077 
00078         virtual void init() { load_images(); }
00079         bool load_images();
00080 
00081     protected:
00082         const std::string img_base_;
00083         std::map<std::string,surface> img_map_;
00084 
00085     private:
00086         bool load_image(const std::string &img_sub);
00087         bool has_background_;
00088         bool initialized_;
00089         bool load_failed_;
00090         int normal_rgb2_, selected_rgb2_, heading_rgb2_;
00091         double normal_alpha2_, selected_alpha2_, heading_alpha2_;
00092         struct bg_cache
00093         {
00094             bg_cache() : surf(), width(-1), height(-1)
00095             {}
00096 
00097             surface surf;
00098             int width, height;
00099         };
00100         bg_cache bg_cache_;
00101     };
00102     friend class style;
00103     friend class imgsel_style;
00104     static style &default_style;
00105     static style simple_style;
00106     static imgsel_style bluebg_style;
00107 
00108     struct item
00109     {
00110         item() : fields(), help(), id(0)
00111         {}
00112 
00113         item(const std::vector<std::string>& fields, size_t id)
00114             : fields(fields), help(), id(id)
00115         {}
00116 
00117         std::vector<std::string> fields;
00118         std::vector<std::string> help;
00119         size_t id;
00120     };
00121 
00122     class sorter
00123     {
00124     public:
00125         virtual ~sorter() {}
00126         virtual bool column_sortable(int column) const = 0;
00127         virtual bool less(int column, const item& row1, const item& row2) const = 0;
00128     };
00129 
00130     class basic_sorter : public sorter
00131     {
00132     public:
00133         basic_sorter();
00134         virtual ~basic_sorter() {}
00135 
00136         basic_sorter& set_alpha_sort(int column);
00137         basic_sorter& set_numeric_sort(int column);
00138         basic_sorter& set_xp_sort(int column);
00139         basic_sorter& set_level_sort(int level_column, int xp_column);
00140         basic_sorter& set_id_sort(int column);
00141         basic_sorter& set_redirect_sort(int column, int to);
00142         basic_sorter& set_position_sort(int column, const std::vector<int>& pos);
00143     protected:
00144         virtual bool column_sortable(int column) const;
00145         virtual bool less(int column, const item& row1, const item& row2) const;
00146 
00147     private:
00148         std::set<int> alpha_sort_, numeric_sort_, id_sort_, xp_sort_, level_sort_;
00149         std::map<int,int> redirect_sort_;
00150         std::map<int,std::vector<int> > pos_sort_;
00151         int xp_col_; //used by level sort
00152     };
00153 
00154     menu(CVideo& video, const std::vector<std::string>& items,
00155          bool click_selects=false, int max_height=-1, int max_width=-1,
00156          const sorter* sorter_obj=NULL, style *menu_style=NULL, const bool auto_join=true);
00157 
00158     /** Default implementation, but defined out-of-line for efficiency reasons. */
00159     ~menu();
00160 
00161     int selection() const;
00162 
00163     void move_selection(size_t id);
00164     void move_selection_keeping_viewport(size_t id);
00165     void reset_selection();
00166 
00167     // allows user to change_item while running (dangerous)
00168     void change_item(int pos1,int pos2,const std::string& str);
00169 
00170     void erase_item(size_t index);
00171 
00172     void set_heading(const std::vector<std::string>& heading);
00173 
00174     /// Set new items to show and redraw/recalculate everything. If
00175     /// strip_spaces is false, spaces will remain at the item edges. If
00176     /// keep_viewport is true, the menu tries to keep the selection at
00177     /// the same position as it were before the items were set.
00178     void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
00179                    bool keep_viewport=false);
00180 
00181     /// Set a new max height for this menu. Note that this does not take
00182     /// effect immediately, only after certain operations that clear
00183     /// everything, such as set_items().
00184     void set_max_height(const int new_max_height);
00185     void set_max_width(const int new_max_width);
00186 
00187     size_t number_of_items() const { return items_.size(); }
00188 
00189     int process();
00190 
00191     bool double_clicked();
00192 
00193     void set_click_selects(bool value);
00194     void set_numeric_keypress_selection(bool value);
00195 
00196     void scroll(unsigned int pos);
00197 
00198     //currently, menus do not manage the memory of their sorter
00199     //this should be changed to a more object-oriented approach
00200     void set_sorter(sorter *s);
00201     void sort_by(int column);
00202     int get_sort_by() {return sortby_;};
00203     bool get_sort_reversed() {return sortreversed_;};
00204 
00205 protected:
00206     bool item_ends_with_image(const std::string& item) const;
00207     virtual void handle_event(const SDL_Event& event);
00208     void set_inner_location(const SDL_Rect& rect);
00209 
00210     bool requires_event_focus(const SDL_Event *event=NULL) const;
00211     const std::vector<int>& column_widths() const;
00212     virtual void draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00213 
00214     style *style_;
00215     bool silent_;
00216 private:
00217     size_t max_items_onscreen() const;
00218 
00219     size_t heading_height() const;
00220 
00221     int max_height_, max_width_;
00222     mutable int max_items_, item_height_;
00223 
00224     void adjust_viewport_to_selection();
00225     void key_press(SDLKey key);
00226 
00227     std::vector<item> items_;
00228     std::vector<size_t> item_pos_;
00229 
00230     std::vector<std::string> heading_;
00231     mutable int heading_height_;
00232 
00233     void create_help_strings();
00234     void process_help_string(int mousex, int mousey);
00235 
00236     std::pair<int,int> cur_help_;
00237     int help_string_;
00238 
00239     mutable std::vector<int> column_widths_;
00240 
00241     size_t selected_;
00242     bool click_selects_;
00243     bool out_;
00244     bool previous_button_;
00245     //std::set<size_t> undrawn_items_;
00246 
00247     bool show_result_;
00248 
00249     bool double_clicked_;
00250 
00251     void column_widths_item(const std::vector<std::string>& row, std::vector<int>& widths) const;
00252 
00253     void clear_item(int item);
00254     void draw_contents();
00255     void draw();
00256     int hit(int x, int y) const;
00257 
00258     std::pair<int,int> hit_cell(int x, int y) const;
00259     int hit_column(int x) const;
00260 
00261     int hit_heading(int x, int y) const;
00262 
00263     mutable std::map<int,SDL_Rect> itemRects_;
00264 
00265     SDL_Rect get_item_rect(int item) const;
00266     SDL_Rect get_item_rect_internal(size_t pos) const;
00267     size_t get_item_height_internal(const std::vector<std::string>& item) const;
00268     size_t get_item_height(int item) const;
00269     int items_start() const;
00270 
00271     int items_end() const;
00272     int items_height() const;
00273 
00274     void update_scrollbar_grip_height();
00275 
00276     ///variable which determines whether a numeric keypress should
00277     ///select an item on the dialog
00278     bool num_selects_;
00279     // These two variables are used to get the correct double click
00280     // behavior so that a click that causes one double click wont be
00281     // counted as a first click in the "next" double click.
00282     bool ignore_next_doubleclick_;
00283     bool last_was_doubleclick_;
00284 
00285     //ellipsis calculation is slightly off, so default to false
00286     bool use_ellipsis_;
00287 
00288     const sorter* sorter_;
00289     int sortby_;
00290     bool sortreversed_;
00291     int highlight_heading_;
00292 
00293     /// Set new items to show. If strip_spaces is false, spaces will
00294     /// remain at the item edges.
00295     void fill_items(const std::vector<std::string>& items, bool strip_spaces);
00296 
00297     void do_sort();
00298     void recalculate_pos();
00299     void assert_pos();
00300 
00301     void update_size();
00302     enum SELECTION_MOVE_VIEWPORT { MOVE_VIEWPORT, NO_MOVE_VIEWPORT };
00303     void set_selection_pos(size_t pos, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
00304     void move_selection_to(size_t id, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
00305     void move_selection_up(size_t dep);
00306     void move_selection_down(size_t dep);
00307 
00308     void invalidate_row(size_t id);
00309     void invalidate_row_pos(size_t pos);
00310     void invalidate_heading();
00311 
00312     std::set<int> invalid_;
00313 };
00314 
00315 
00316 
00317 }
00318 
00319 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:15 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs