menu_style.cpp

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

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs