The Battle for Wesnoth  1.13.11+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
menu_style.cpp
Go to the documentation of this file.
1 /*
2  wesnoth menu styles Copyright (C) 2006 - 2018 by Patrick Parker <patrick_x99@hotmail.com>
3  wesnoth menu Copyright (C) 2003-5 by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
18 #include "widgets/menu.hpp"
19 
20 #include "font/sdl_ttf.hpp"
21 #include "image.hpp"
22 #include "sdl/utils.hpp"
23 #include "video.hpp"
24 
25 namespace gui {
26 
27  //static initializations
28 menu::imgsel_style menu::bluebg_style("dialogs/selection", true,
29  0x000000, 0x000000, 0x333333,
30  0.35, 0.0, 0.3);
32 
34 
35  //constructors
37  cell_padding_(font::SIZE_NORMAL * 3/5), thickness_(0),
38  normal_rgb_(0x000000), selected_rgb_(0x000099), heading_rgb_(0x333333),
39  normal_alpha_(0.2), selected_alpha_(0.6), heading_alpha_(0.3),
40  max_img_w_(-1), max_img_h_(-1)
41 {}
42 
44 {}
45 menu::imgsel_style::imgsel_style(const std::string &img_base, bool has_bg,
46  int normal_rgb, int selected_rgb, int heading_rgb,
47  double normal_alpha, double selected_alpha, double heading_alpha)
48  : img_base_(img_base), has_background_(has_bg), initialized_(false), load_failed_(false),
49  normal_rgb2_(normal_rgb), selected_rgb2_(selected_rgb), heading_rgb2_(heading_rgb),
50  normal_alpha2_(normal_alpha), selected_alpha2_(selected_alpha), heading_alpha2_(heading_alpha)
51 {}
53 {}
54 
55 size_t menu::style::get_font_size() const { return font_size_; }
56 size_t menu::style::get_cell_padding() const { return cell_padding_; }
57 size_t menu::style::get_thickness() const { return thickness_; }
58 
59 void menu::style::scale_images(int max_width, int max_height)
60 {
61  max_img_w_ = max_width;
62  max_img_h_ = max_height;
63 }
64 
66 {
67  surface surf = image::get_image(img_loc);
68  if(!surf.null())
69  {
70  int scale = 100;
71  if(max_img_w_ > 0 && surf->w > max_img_w_) {
72  scale = (max_img_w_ * 100) / surf->w;
73  }
74  if(max_img_h_ > 0 && surf->h > max_img_h_) {
75  scale = std::min<int>(scale, ((max_img_h_ * 100) / surf->h));
76  }
77  if(scale != 100)
78  {
79  return scale_surface(surf, (scale * surf->w)/100, (scale * surf->h)/100);
80  }
81  }
82  return surf;
83 }
84 
86 {
87  std::string path = img_base_ + "-" + img_sub + ".png";
88  const surface image = image::get_image(path);
89  img_map_[img_sub] = image;
90  return(!image.null());
91 }
92 
94 {
95  if(!initialized_)
96  {
97 
98  if( load_image("border-botleft")
99  && load_image("border-botright")
100  && load_image("border-topleft")
101  && load_image("border-topright")
102  && load_image("border-left")
103  && load_image("border-right")
104  && load_image("border-top")
105  && load_image("border-bottom") )
106  {
107  thickness_ = std::min(
108  img_map_["border-top"]->h,
109  img_map_["border-left"]->w);
110 
111 
112  if(has_background_ && !load_image("background"))
113  {
114  load_failed_ = true;
115  }
116  else
117  {
118  normal_rgb_ = normal_rgb2_;
119  normal_alpha_ = normal_alpha2_;
120  selected_rgb_ = selected_rgb2_;
121  selected_alpha_ = selected_alpha2_;
122  heading_rgb_ = heading_rgb2_;
123  heading_alpha_ = heading_alpha2_;
124 
125  load_failed_ = false;
126  }
127  initialized_ = true;
128  }
129  else
130  {
131  thickness_ = 0;
132  initialized_ = true;
133  load_failed_ = true;
134  }
135  }
136  return (!load_failed_);
137 }
138 
139 void menu::imgsel_style::draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
140 {
141  if(type == SELECTED_ROW && has_background_ && !load_failed_) {
142  if(bg_cache_.width != rect.w || bg_cache_.height != rect.h)
143  {
144  //draw scaled background image
145  //scale image each time (to prevent loss of quality)
146  bg_cache_.surf = scale_surface(img_map_["background"], rect.w, rect.h);
147  bg_cache_.width = rect.w;
148  bg_cache_.height = rect.h;
149  }
150  SDL_Rect clip = rect;
151  menu_ref.video().blit_surface(rect.x,rect.y,bg_cache_.surf,nullptr,&clip);
152  }
153  else {
154  style::draw_row_bg(menu_ref, row_index, rect, type);
155  }
156 }
157 
158 void menu::imgsel_style::draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
159 {
160  if(!load_failed_) {
161  //draw item inside
162  style::draw_row(menu_ref, row_index, rect, type);
163 
164  if(type == SELECTED_ROW) {
165  // draw border
166  surface image;
167  SDL_Rect area;
168  SDL_Rect clip = rect;
169  area.x = rect.x;
170  area.y = rect.y;
171 
172  image = img_map_["border-top"];
173  area.x = rect.x;
174  area.y = rect.y;
175  do {
176  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
177  area.x += image->w;
178  } while( area.x < rect.x + rect.w );
179 
180  image = img_map_["border-left"];
181  area.x = rect.x;
182  area.y = rect.y;
183  do {
184  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
185  area.y += image->h;
186  } while( area.y < rect.y + rect.h );
187 
188  image = img_map_["border-right"];
189  area.x = rect.x + rect.w - thickness_;
190  area.y = rect.y;
191  do {
192  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
193  area.y += image->h;
194  } while( area.y < rect.y + rect.h );
195 
196  image = img_map_["border-bottom"];
197  area.x = rect.x;
198  area.y = rect.y + rect.h - thickness_;
199  do {
200  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
201  area.x += image->w;
202  } while( area.x < rect.x + rect.w );
203 
204  image = img_map_["border-topleft"];
205  area.x = rect.x;
206  area.y = rect.y;
207  menu_ref.video().blit_surface(area.x,area.y,image);
208 
209  image = img_map_["border-topright"];
210  area.x = rect.x + rect.w - image->w;
211  area.y = rect.y;
212  menu_ref.video().blit_surface(area.x,area.y,image);
213 
214  image = img_map_["border-botleft"];
215  area.x = rect.x;
216  area.y = rect.y + rect.h - image->h;
217  menu_ref.video().blit_surface(area.x,area.y,image);
218 
219  image = img_map_["border-botright"];
220  area.x = rect.x + rect.w - image->w;
221  area.y = rect.y + rect.h - image->h;
222  menu_ref.video().blit_surface(area.x,area.y,image);
223  }
224  }
225  else {
226  //default drawing
227  style::draw_row(menu_ref, row_index, rect, type);
228  }
229 }
230 
232 {
233  SDL_Rect bounds = style::item_size(item);
234 
235  bounds.w += 2 * thickness_;
236  bounds.h += 2 * thickness_;
237 
238  return bounds;
239 }
240 
241 
242 } //namesapce gui
static style simple_style
Definition: menu.hpp:102
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:920
size_t get_font_size() const
Definition: menu_style.cpp:55
virtual void draw_row(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:158
virtual void draw_row_bg(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:822
std::vector< char_t > string
imgsel_style(const std::string &img_base, bool has_bg, int normal_rgb, int selected_rgb, int heading_rgb, double normal_alpha, double selected_alpha, double heading_alpha)
Definition: menu_style.cpp:45
Note: Specific to sdl_ttf.
bool null() const
Definition: surface.hpp:79
ROW_TYPE
Definition: menu.hpp:32
CVideo & video() const
Definition: widget.hpp:84
General purpose widgets.
bool load_image(const std::string &img_sub)
Definition: menu_style.cpp:85
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu_style.cpp:231
#define h
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
Definition: utils.cpp:272
void blit_surface(int x, int y, surface surf, SDL_Rect *srcrect=nullptr, SDL_Rect *clip_rect=nullptr)
Draws a surface directly onto the screen framebuffer.
Definition: video.cpp:162
surface get_item_image(const image::locator &i_locator) const
Definition: menu_style.cpp:65
-file util.hpp
static imgsel_style bluebg_style
Definition: menu.hpp:103
const int SIZE_NORMAL
Definition: constants.cpp:19
friend class style
Definition: menu.hpp:99
virtual void draw_row_bg(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:139
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
Definition: xbrz.cpp:1190
size_t get_thickness() const
Definition: menu_style.cpp:57
std::string path
Definition: game_config.cpp:56
static style & default_style
Definition: menu.hpp:101
int w
void scale_images(int max_width, int max_height)
Definition: menu_style.cpp:59
virtual ~style()
Definition: menu_style.cpp:43
this module manages the cache of images.
Definition: image.cpp:103
virtual void draw_row(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:851
friend class imgsel_style
Definition: menu.hpp:100
size_t get_cell_padding() const
Definition: menu_style.cpp:56
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu.cpp:793