00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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_;
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
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_;
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
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
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
00175
00176
00177
00178 void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
00179 bool keep_viewport=false);
00180
00181
00182
00183
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
00199
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
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
00277
00278 bool num_selects_;
00279
00280
00281
00282 bool ignore_next_doubleclick_;
00283 bool last_was_doubleclick_;
00284
00285
00286 bool use_ellipsis_;
00287
00288 const sorter* sorter_;
00289 int sortby_;
00290 bool sortreversed_;
00291 int highlight_heading_;
00292
00293
00294
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