00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define GETTEXT_DOMAIN "wesnoth-lib"
00018
00019 #include "global.hpp"
00020
00021 #include "widgets/menu.hpp"
00022
00023 #include "font.hpp"
00024 #include "image.hpp"
00025 #include "video.hpp"
00026
00027 namespace gui {
00028
00029
00030 menu::imgsel_style menu::bluebg_style("misc/selection2", true,
00031 0x000000, 0x000000, 0x333333,
00032 0.35, 0.0, 0.3);
00033 menu::style menu::simple_style;
00034
00035 menu::style &menu::default_style = menu::bluebg_style;
00036 menu *empty_menu = NULL;
00037
00038
00039 menu::style::style() : font_size_(font::SIZE_NORMAL),
00040 cell_padding_(font::SIZE_NORMAL * 3/5), thickness_(0),
00041 normal_rgb_(0x000000), selected_rgb_(0x000099), heading_rgb_(0x333333),
00042 normal_alpha_(0.2), selected_alpha_(0.6), heading_alpha_(0.3),
00043 max_img_w_(-1), max_img_h_(-1)
00044 {}
00045
00046 menu::style::~style()
00047 {}
00048 menu::imgsel_style::imgsel_style(const std::string &img_base, bool has_bg,
00049 int normal_rgb, int selected_rgb, int heading_rgb,
00050 double normal_alpha, double selected_alpha, double heading_alpha)
00051 : img_base_(img_base), has_background_(has_bg), initialized_(false), load_failed_(false),
00052 normal_rgb2_(normal_rgb), selected_rgb2_(selected_rgb), heading_rgb2_(heading_rgb),
00053 normal_alpha2_(normal_alpha), selected_alpha2_(selected_alpha), heading_alpha2_(heading_alpha)
00054 {}
00055 menu::imgsel_style::~imgsel_style()
00056 {}
00057
00058 size_t menu::style::get_font_size() const { return font_size_; }
00059 size_t menu::style::get_cell_padding() const { return cell_padding_; }
00060 size_t menu::style::get_thickness() const { return thickness_; }
00061
00062 void menu::style::scale_images(int max_width, int max_height)
00063 {
00064 max_img_w_ = max_width;
00065 max_img_h_ = max_height;
00066 }
00067
00068 surface menu::style::get_item_image(const image::locator& img_loc) const
00069 {
00070 surface surf = image::get_image(img_loc);
00071 if(!surf.null())
00072 {
00073 int scale = 100;
00074 if(max_img_w_ > 0 && surf->w > max_img_w_) {
00075 scale = (max_img_w_ * 100) / surf->w;
00076 }
00077 if(max_img_h_ > 0 && surf->h > max_img_h_) {
00078 scale = std::min<int>(scale, ((max_img_h_ * 100) / surf->h));
00079 }
00080 if(scale != 100)
00081 {
00082 return scale_surface(surf, (scale * surf->w)/100, (scale * surf->h)/100);
00083 }
00084 }
00085 return surf;
00086 }
00087
00088 bool menu::imgsel_style::load_image(const std::string &img_sub)
00089 {
00090 std::string path = img_base_ + "-" + img_sub + ".png";
00091 const surface image = image::get_image(path);
00092 img_map_[img_sub] = image;
00093 return(!image.null());
00094 }
00095
00096 bool menu::imgsel_style::load_images()
00097 {
00098 if(!initialized_)
00099 {
00100
00101 if( load_image("border-botleft")
00102 && load_image("border-botright")
00103 && load_image("border-topleft")
00104 && load_image("border-topright")
00105 && load_image("border-left")
00106 && load_image("border-right")
00107 && load_image("border-top")
00108 && load_image("border-bottom") )
00109 {
00110 thickness_ = std::min(
00111 img_map_["border-top"]->h,
00112 img_map_["border-left"]->w);
00113
00114 if(has_background_ && !load_image("background"))
00115 {
00116 load_failed_ = true;
00117 }
00118 else
00119 {
00120 normal_rgb_ = normal_rgb2_;
00121 normal_alpha_ = normal_alpha2_;
00122 selected_rgb_ = selected_rgb2_;
00123 selected_alpha_ = selected_alpha2_;
00124 heading_rgb_ = heading_rgb2_;
00125 heading_alpha_ = heading_alpha2_;
00126
00127 load_failed_ = false;
00128 }
00129 initialized_ = true;
00130 }
00131 else
00132 {
00133 thickness_ = 0;
00134 initialized_ = true;
00135 load_failed_ = true;
00136 }
00137 }
00138 return (!load_failed_);
00139 }
00140
00141 void menu::imgsel_style::draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
00142 {
00143 if(type == SELECTED_ROW && has_background_ && !load_failed_) {
00144 if(bg_cache_.width != rect.w || bg_cache_.height != rect.h)
00145 {
00146
00147
00148 bg_cache_.surf = scale_surface(img_map_["background"], rect.w, rect.h);
00149 bg_cache_.width = rect.w;
00150 bg_cache_.height = rect.h;
00151 }
00152 SDL_Rect clip = rect;
00153 menu_ref.video().blit_surface(rect.x,rect.y,bg_cache_.surf,NULL,&clip);
00154 }
00155 else {
00156 style::draw_row_bg(menu_ref, row_index, rect, type);
00157 }
00158 }
00159
00160 void menu::imgsel_style::draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
00161 {
00162 if(!load_failed_) {
00163
00164 style::draw_row(menu_ref, row_index, rect, type);
00165
00166 if(type == SELECTED_ROW) {
00167
00168 surface image;
00169 SDL_Rect area;
00170 SDL_Rect clip = rect;
00171 area.x = rect.x;
00172 area.y = rect.y;
00173
00174 image = img_map_["border-top"];
00175 area.x = rect.x;
00176 area.y = rect.y;
00177 do {
00178 menu_ref.video().blit_surface(area.x,area.y,image,NULL,&clip);
00179 area.x += image->w;
00180 } while( area.x < rect.x + rect.w );
00181
00182 image = img_map_["border-left"];
00183 area.x = rect.x;
00184 area.y = rect.y;
00185 do {
00186 menu_ref.video().blit_surface(area.x,area.y,image,NULL,&clip);
00187 area.y += image->h;
00188 } while( area.y < rect.y + rect.h );
00189
00190 image = img_map_["border-right"];
00191 area.x = rect.x + rect.w - thickness_;
00192 area.y = rect.y;
00193 do {
00194 menu_ref.video().blit_surface(area.x,area.y,image,NULL,&clip);
00195 area.y += image->h;
00196 } while( area.y < rect.y + rect.h );
00197
00198 image = img_map_["border-bottom"];
00199 area.x = rect.x;
00200 area.y = rect.y + rect.h - thickness_;
00201 do {
00202 menu_ref.video().blit_surface(area.x,area.y,image,NULL,&clip);
00203 area.x += image->w;
00204 } while( area.x < rect.x + rect.w );
00205
00206 image = img_map_["border-topleft"];
00207 area.x = rect.x;
00208 area.y = rect.y;
00209 menu_ref.video().blit_surface(area.x,area.y,image);
00210
00211 image = img_map_["border-topright"];
00212 area.x = rect.x + rect.w - image->w;
00213 area.y = rect.y;
00214 menu_ref.video().blit_surface(area.x,area.y,image);
00215
00216 image = img_map_["border-botleft"];
00217 area.x = rect.x;
00218 area.y = rect.y + rect.h - image->h;
00219 menu_ref.video().blit_surface(area.x,area.y,image);
00220
00221 image = img_map_["border-botright"];
00222 area.x = rect.x + rect.w - image->w;
00223 area.y = rect.y + rect.h - image->h;
00224 menu_ref.video().blit_surface(area.x,area.y,image);
00225 }
00226 } else {
00227
00228 style::draw_row(menu_ref, row_index, rect, type);
00229 }
00230 }
00231
00232 SDL_Rect menu::imgsel_style::item_size(const std::string& item) const
00233 {
00234 SDL_Rect bounds = style::item_size(item);
00235
00236 bounds.w += 2 * thickness_;
00237 bounds.h += 2 * thickness_;
00238
00239 return bounds;
00240 }
00241
00242
00243 }