00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef WIDGET_MENU_HPP_INCLUDED
00016 #define WIDGET_MENU_HPP_INCLUDED
00017
00018 #include <map>
00019 #include <set>
00020 #include <string>
00021 #include <vector>
00022
00023
00024 #include "../image.hpp"
00025 #include "../events.hpp"
00026 #include "../sdl_utils.hpp"
00027
00028 #include "scrollarea.hpp"
00029
00030 #include "SDL.h"
00031
00032 namespace gui {
00033
00034 class menu;
00035 extern menu *empty_menu;
00036
00037 class menu : public scrollarea
00038 {
00039 public:
00040
00041 enum ROW_TYPE { NORMAL_ROW, SELECTED_ROW, HEADING_ROW };
00042
00043 class style
00044 {
00045 public:
00046 style();
00047 virtual ~style();
00048 virtual void init() {}
00049
00050 virtual SDL_Rect item_size(const std::string& item) const;
00051 virtual void draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00052 virtual void draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00053 void scale_images(int max_width, int max_height);
00054
00055 surface get_item_image(const image::locator &i_locator) const;
00056 size_t get_font_size() const;
00057 size_t get_cell_padding() const;
00058 size_t get_thickness() const;
00059
00060 protected:
00061 size_t font_size_;
00062 size_t cell_padding_;
00063 size_t thickness_;
00064
00065 int normal_rgb_, selected_rgb_, heading_rgb_;
00066 double normal_alpha_, selected_alpha_, heading_alpha_;
00067 int max_img_w_, max_img_h_;
00068 };
00069
00070
00071 class imgsel_style : public style
00072 {
00073 public:
00074 imgsel_style(const std::string &img_base, bool has_bg,
00075 int normal_rgb, int selected_rgb, int heading_rgb,
00076 double normal_alpha, double selected_alpha, double heading_alpha);
00077 virtual ~imgsel_style();
00078
00079 virtual SDL_Rect item_size(const std::string& item) const;
00080 virtual void draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00081 virtual void draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00082
00083 virtual void init() { load_images(); }
00084 bool load_images();
00085
00086 protected:
00087 const std::string img_base_;
00088 std::map<std::string,surface> img_map_;
00089
00090 private:
00091 bool load_image(const std::string &img_sub);
00092 bool has_background_;
00093 bool initialized_;
00094 bool load_failed_;
00095 int normal_rgb2_, selected_rgb2_, heading_rgb2_;
00096 double normal_alpha2_, selected_alpha2_, heading_alpha2_;
00097 struct bg_cache
00098 {
00099 bg_cache() : surf(), width(-1), height(-1)
00100 {}
00101
00102 surface surf;
00103 int width, height;
00104 };
00105 bg_cache bg_cache_;
00106 };
00107 friend class style;
00108 friend class imgsel_style;
00109 static style &default_style;
00110 static style simple_style;
00111 static imgsel_style bluebg_style;
00112
00113 struct item
00114 {
00115 item() : fields(), help(), id(0)
00116 {}
00117
00118 item(const std::vector<std::string>& fields, size_t id)
00119 : fields(fields), help(), id(id)
00120 {}
00121
00122 std::vector<std::string> fields;
00123 std::vector<std::string> help;
00124 size_t id;
00125 };
00126
00127 class sorter
00128 {
00129 public:
00130 virtual ~sorter() {}
00131 virtual bool column_sortable(int column) const = 0;
00132 virtual bool less(int column, const item& row1, const item& row2) const = 0;
00133 };
00134
00135 class basic_sorter : public sorter
00136 {
00137 public:
00138 basic_sorter();
00139 virtual ~basic_sorter() {}
00140
00141 basic_sorter& set_alpha_sort(int column);
00142 basic_sorter& set_numeric_sort(int column);
00143 basic_sorter& set_id_sort(int column);
00144 basic_sorter& set_redirect_sort(int column, int to);
00145 basic_sorter& set_position_sort(int column, const std::vector<int>& pos);
00146 protected:
00147 virtual bool column_sortable(int column) const;
00148 virtual bool less(int column, const item& row1, const item& row2) const;
00149
00150 private:
00151 std::set<int> alpha_sort_, numeric_sort_, id_sort_;
00152 std::map<int,int> redirect_sort_;
00153 std::map<int,std::vector<int> > pos_sort_;
00154 };
00155
00156 menu(CVideo& video, const std::vector<std::string>& items,
00157 bool click_selects=false, int max_height=-1, int max_width=-1,
00158 const sorter* sorter_obj=NULL, style *menu_style=NULL, const bool auto_join=true);
00159
00160 int selection() const;
00161
00162 void move_selection(size_t id);
00163 void reset_selection();
00164
00165
00166 void change_item(int pos1,int pos2,const std::string& str);
00167
00168 void erase_item(size_t index);
00169
00170 void set_heading(const std::vector<std::string>& heading);
00171
00172
00173
00174
00175
00176 void set_items(const std::vector<std::string>& items, bool strip_spaces=true,
00177 bool keep_viewport=false);
00178
00179
00180
00181
00182 void set_max_height(const int new_max_height);
00183 void set_max_width(const int new_max_width);
00184
00185 size_t nitems() const { return items_.size(); }
00186
00187 int process();
00188
00189 bool double_clicked();
00190
00191 void set_click_selects(bool value);
00192 void set_numeric_keypress_selection(bool value);
00193
00194 void scroll(unsigned int pos);
00195
00196
00197
00198 void set_sorter(sorter *s);
00199 void sort_by(int column);
00200 void wrap_words();
00201
00202 protected:
00203 bool item_ends_with_image(const std::string& item) const;
00204 virtual void handle_event(const SDL_Event& event);
00205 void set_inner_location(const SDL_Rect& rect);
00206
00207 bool requires_event_focus(const SDL_Event *event=NULL) const;
00208 const std::vector<int>& column_widths() const;
00209 virtual void draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
00210
00211 style *style_;
00212 bool silent_;
00213 private:
00214 size_t max_items_onscreen() const;
00215
00216 size_t heading_height() const;
00217
00218 int max_height_, max_width_;
00219 mutable int max_items_, item_height_;
00220
00221 void adjust_viewport_to_selection();
00222 void key_press(SDLKey key);
00223
00224 std::vector<item> items_;
00225 std::vector<size_t> item_pos_;
00226
00227 std::vector<std::string> heading_;
00228 mutable int heading_height_;
00229
00230 void create_help_strings();
00231 void process_help_string(int mousex, int mousey);
00232
00233 std::pair<int,int> cur_help_;
00234 int help_string_;
00235
00236 mutable std::vector<int> column_widths_;
00237
00238 size_t selected_;
00239 bool click_selects_;
00240 bool out_;
00241 bool previous_button_;
00242
00243
00244 bool show_result_;
00245
00246 bool double_clicked_;
00247
00248 void column_widths_item(const std::vector<std::string>& row, std::vector<int>& widths) const;
00249
00250 void clear_item(int item);
00251 void draw_contents();
00252 void draw();
00253 int hit(int x, int y) const;
00254
00255 std::pair<int,int> hit_cell(int x, int y) const;
00256 int hit_column(int x) const;
00257
00258 int hit_heading(int x, int y) const;
00259
00260 mutable std::map<int,SDL_Rect> itemRects_;
00261
00262 SDL_Rect get_item_rect(int item) const;
00263 SDL_Rect get_item_rect_internal(size_t pos) const;
00264 size_t get_item_height_internal(const std::vector<std::string>& item) const;
00265 size_t get_item_height(int item) const;
00266 int items_start() const;
00267
00268 int items_end() const;
00269 int items_height() const;
00270
00271 void update_scrollbar_grip_height();
00272
00273
00274
00275 bool num_selects_;
00276
00277
00278
00279 bool ignore_next_doubleclick_;
00280 bool last_was_doubleclick_;
00281
00282
00283 bool use_ellipsis_;
00284
00285 const sorter* sorter_;
00286 int sortby_;
00287 bool sortreversed_;
00288 int highlight_heading_;
00289
00290
00291
00292 void fill_items(const std::vector<std::string>& items, bool strip_spaces);
00293
00294 void do_sort();
00295 void recalculate_pos();
00296 void assert_pos();
00297
00298 void update_size();
00299 enum SELECTION_MOVE_VIEWPORT { MOVE_VIEWPORT, NO_MOVE_VIEWPORT };
00300 void set_selection_pos(size_t pos, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
00301 void move_selection_to(size_t id, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
00302 void move_selection_up(size_t dep);
00303 void move_selection_down(size_t dep);
00304
00305 void invalidate_row(size_t id);
00306 void invalidate_row_pos(size_t pos);
00307 void invalidate_heading();
00308
00309 std::set<int> invalid_;
00310 };
00311
00312
00313
00314 }
00315
00316 #endif