The Battle for Wesnoth  1.13.4+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 - 2016 by Patrick Parker <[email protected]>
3  wesnoth menu Copyright (C) 2003-5 by David White <[email protected]>
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 "global.hpp"
19 
20 #include "widgets/menu.hpp"
21 
22 #include "font.hpp"
23 #include "image.hpp"
24 #include "video.hpp"
25 
26 namespace gui {
27 
28  //static initializations
29 menu::imgsel_style menu::bluebg_style("dialogs/selection", true,
30  0x000000, 0x000000, 0x333333,
31  0.35, 0.0, 0.3);
33 
35 
36  //constructors
38  cell_padding_(font::SIZE_NORMAL * 3/5), thickness_(0),
39  normal_rgb_(0x000000), selected_rgb_(0x000099), heading_rgb_(0x333333),
40 #ifdef SDL_GPU
41  normal_alpha_(50), selected_alpha_(150), heading_alpha_(75),
42 #else
43  normal_alpha_(0.2), selected_alpha_(0.6), heading_alpha_(0.3),
44 #endif
45  max_img_w_(-1), max_img_h_(-1)
46 {}
47 
49 {}
50 menu::imgsel_style::imgsel_style(const std::string &img_base, bool has_bg,
51  int normal_rgb, int selected_rgb, int heading_rgb,
52  double normal_alpha, double selected_alpha, double heading_alpha)
53  : img_base_(img_base), has_background_(has_bg), initialized_(false), load_failed_(false),
54  normal_rgb2_(normal_rgb), selected_rgb2_(selected_rgb), heading_rgb2_(heading_rgb),
55  normal_alpha2_(normal_alpha), selected_alpha2_(selected_alpha), heading_alpha2_(heading_alpha)
56 {}
58 {}
59 
60 size_t menu::style::get_font_size() const { return font_size_; }
61 size_t menu::style::get_cell_padding() const { return cell_padding_; }
62 size_t menu::style::get_thickness() const { return thickness_; }
63 
64 void menu::style::scale_images(int max_width, int max_height)
65 {
66  max_img_w_ = max_width;
67  max_img_h_ = max_height;
68 }
69 
70 #ifdef SDL_GPU
71 sdl::timage menu::style::get_item_image(const image::locator& img_loc) const
72 {
73  sdl::timage img = image::get_texture(img_loc);
74  if(!img.null())
75  {
76  int scale = 100;
77  if(max_img_w_ > 0 && img.width() > max_img_w_) {
78  scale = (max_img_w_ * 100) / img.width();
79  }
80  if(max_img_h_ > 0 && img.height() > max_img_h_) {
81  scale = std::min<int>(scale, ((max_img_h_ * 100) / img.height()));
82  }
83  if(scale != 100)
84  {
85  img.set_scale(scale, scale);
86  return img;
87  }
88  }
89  return img;
90 }
91 #else
93 {
94  surface surf = image::get_image(img_loc);
95  if(!surf.null())
96  {
97  int scale = 100;
98  if(max_img_w_ > 0 && surf->w > max_img_w_) {
99  scale = (max_img_w_ * 100) / surf->w;
100  }
101  if(max_img_h_ > 0 && surf->h > max_img_h_) {
102  scale = std::min<int>(scale, ((max_img_h_ * 100) / surf->h));
103  }
104  if(scale != 100)
105  {
106  return scale_surface(surf, (scale * surf->w)/100, (scale * surf->h)/100);
107  }
108  }
109  return surf;
110 }
111 #endif
112 
114 {
115 #ifdef SDL_GPU
116  std::string path = img_base_ + "-" + img_sub + ".png";
117  sdl::timage image = image::get_image(path);
118  img_map_[img_sub] = image;
119  return(!image.null());
120 #else
121  std::string path = img_base_ + "-" + img_sub + ".png";
122  const surface image = image::get_image(path);
123  img_map_[img_sub] = image;
124  return(!image.null());
125 #endif
126 }
127 
129 {
130  if(!initialized_)
131  {
132 
133  if( load_image("border-botleft")
134  && load_image("border-botright")
135  && load_image("border-topleft")
136  && load_image("border-topright")
137  && load_image("border-left")
138  && load_image("border-right")
139  && load_image("border-top")
140  && load_image("border-bottom") )
141  {
142 #ifdef SDL_GPU
143  thickness_ = std::min(
144  img_map_["border-top"].height(),
145  img_map_["border-left"].width());
146 #else
147  thickness_ = std::min(
148  img_map_["border-top"]->h,
149  img_map_["border-left"]->w);
150 #endif
151 
152 
153  if(has_background_ && !load_image("background"))
154  {
155  load_failed_ = true;
156  }
157  else
158  {
159  normal_rgb_ = normal_rgb2_;
160  normal_alpha_ = normal_alpha2_;
161  selected_rgb_ = selected_rgb2_;
162  selected_alpha_ = selected_alpha2_;
163  heading_rgb_ = heading_rgb2_;
164  heading_alpha_ = heading_alpha2_;
165 
166  load_failed_ = false;
167  }
168  initialized_ = true;
169  }
170  else
171  {
172  thickness_ = 0;
173  initialized_ = true;
174  load_failed_ = true;
175  }
176  }
177  return (!load_failed_);
178 }
179 
180 void menu::imgsel_style::draw_row_bg(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
181 {
182 #ifdef SDL_GPU
183  if(type == SELECTED_ROW && has_background_ && !load_failed_) {
184  background_image_.set_scale(float(rect.w) / background_image_.width(),
185  float(rect.h) / background_image_.height());
186  menu_ref.video().draw_texture(background_image_, rect.x, rect.y);
187  }
188 #else
189  if(type == SELECTED_ROW && has_background_ && !load_failed_) {
190  if(bg_cache_.width != rect.w || bg_cache_.height != rect.h)
191  {
192  //draw scaled background image
193  //scale image each time (to prevent loss of quality)
194  bg_cache_.surf = scale_surface(img_map_["background"], rect.w, rect.h);
195  bg_cache_.width = rect.w;
196  bg_cache_.height = rect.h;
197  }
198  SDL_Rect clip = rect;
199  menu_ref.video().blit_surface(rect.x,rect.y,bg_cache_.surf,nullptr,&clip);
200  }
201 #endif
202  else {
203  style::draw_row_bg(menu_ref, row_index, rect, type);
204  }
205 }
206 
207 void menu::imgsel_style::draw_row(menu& menu_ref, const size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
208 {
209  if(!load_failed_) {
210  //draw item inside
211  style::draw_row(menu_ref, row_index, rect, type);
212 
213 #ifdef SDL_GPU
214  if(type == SELECTED_ROW) {
215  // draw border
216  sdl::timage image;
217  SDL_Rect area;
218  area.x = rect.x;
219  area.y = rect.y;
220 
221  GPU_SetClip(get_render_target(), rect.x, rect.y, rect.w, rect.h);
222 
223  image = img_map_["border-top"];
224  area.x = rect.x;
225  area.y = rect.y;
226  do {
227  menu_ref.video().draw_texture(image, area.x, area.y);
228  area.x += image.width();
229  } while( area.x < rect.x + rect.w );
230 
231  image = img_map_["border-left"];
232  area.x = rect.x;
233  area.y = rect.y;
234  do {
235  menu_ref.video().draw_texture(image, area.x, area.y);
236  area.y += image.height();
237  } while( area.y < rect.y + rect.h );
238 
239  image = img_map_["border-right"];
240  area.x = rect.x + rect.w - thickness_;
241  area.y = rect.y;
242  do {
243  menu_ref.video().draw_texture(image, area.x, area.y);
244  area.y += image.height();
245  } while( area.y < rect.y + rect.h );
246 
247  image = img_map_["border-bottom"];
248  area.x = rect.x;
249  area.y = rect.y + rect.h - thickness_;
250  do {
251  menu_ref.video().draw_texture(image, area.x, area.y);
252  area.x += image.width();
253  } while( area.x < rect.x + rect.w );
254 
255  image = img_map_["border-topleft"];
256  area.x = rect.x;
257  area.y = rect.y;
258  menu_ref.video().draw_texture(image, area.x, area.y);
259 
260  image = img_map_["border-topright"];
261  area.x = rect.x + rect.w - image.width();
262  area.y = rect.y;
263  menu_ref.video().draw_texture(image, area.x, area.y);
264 
265  image = img_map_["border-botleft"];
266  area.x = rect.x;
267  area.y = rect.y + rect.h - image.height();
268  menu_ref.video().draw_texture(image, area.x, area.y);
269 
270  image = img_map_["border-botright"];
271  area.x = rect.x + rect.w - image.width();
272  area.y = rect.y + rect.h - image.height();
273  menu_ref.video().draw_texture(image, area.x, area.y);
274 
275  GPU_UnsetClip(get_render_target());
276  }
277  }
278 #else
279  if(type == SELECTED_ROW) {
280  // draw border
281  surface image;
282  SDL_Rect area;
283  SDL_Rect clip = rect;
284  area.x = rect.x;
285  area.y = rect.y;
286 
287  image = img_map_["border-top"];
288  area.x = rect.x;
289  area.y = rect.y;
290  do {
291  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
292  area.x += image->w;
293  } while( area.x < rect.x + rect.w );
294 
295  image = img_map_["border-left"];
296  area.x = rect.x;
297  area.y = rect.y;
298  do {
299  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
300  area.y += image->h;
301  } while( area.y < rect.y + rect.h );
302 
303  image = img_map_["border-right"];
304  area.x = rect.x + rect.w - thickness_;
305  area.y = rect.y;
306  do {
307  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
308  area.y += image->h;
309  } while( area.y < rect.y + rect.h );
310 
311  image = img_map_["border-bottom"];
312  area.x = rect.x;
313  area.y = rect.y + rect.h - thickness_;
314  do {
315  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
316  area.x += image->w;
317  } while( area.x < rect.x + rect.w );
318 
319  image = img_map_["border-topleft"];
320  area.x = rect.x;
321  area.y = rect.y;
322  menu_ref.video().blit_surface(area.x,area.y,image);
323 
324  image = img_map_["border-topright"];
325  area.x = rect.x + rect.w - image->w;
326  area.y = rect.y;
327  menu_ref.video().blit_surface(area.x,area.y,image);
328 
329  image = img_map_["border-botleft"];
330  area.x = rect.x;
331  area.y = rect.y + rect.h - image->h;
332  menu_ref.video().blit_surface(area.x,area.y,image);
333 
334  image = img_map_["border-botright"];
335  area.x = rect.x + rect.w - image->w;
336  area.y = rect.y + rect.h - image->h;
337  menu_ref.video().blit_surface(area.x,area.y,image);
338  }
339  }
340 #endif
341  else {
342  //default drawing
343  style::draw_row(menu_ref, row_index, rect, type);
344  }
345 }
346 
348 {
349  SDL_Rect bounds = style::item_size(item);
350 
351  bounds.w += 2 * thickness_;
352  bounds.h += 2 * thickness_;
353 
354  return bounds;
355 }
356 
357 
358 } //namesapce gui
static style simple_style
Definition: menu.hpp:117
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
void GPU_UnsetClip(GPU_Target *target)
Definition: SDL_gpu.c:1833
size_t get_font_size() const
Definition: menu_style.cpp:60
bool initialized_
Definition: font.cpp:609
size_t thickness_
Definition: menu.hpp:57
bool null() const
Definition: utils.hpp:104
virtual void draw_row(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:207
virtual void draw_row_bg(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:844
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:10669
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:50
Graphical text output.
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
ROW_TYPE
Definition: menu.hpp:32
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
bool load_image(const std::string &img_sub)
Definition: menu_style.cpp:113
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu_style.cpp:347
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glew.h:3783
surface scale_surface(const surface &surf, int w, int h)
Definition: utils.cpp:443
void blit_surface(int x, int y, surface surf, SDL_Rect *srcrect=nullptr, SDL_Rect *clip_rect=nullptr)
Definition: video.cpp:290
surface get_item_image(const image::locator &i_locator) const
Definition: menu_style.cpp:92
-file util.hpp
static imgsel_style bluebg_style
Definition: menu.hpp:118
unsigned thickness_
The thickness of the line.
Definition: canvas.cpp:293
const int SIZE_NORMAL
Definition: font.hpp:58
friend class style
Definition: menu.hpp:114
virtual void draw_row_bg(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:180
GLsizei const char ** path
Definition: glew.h:4654
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
size_t get_thickness() const
Definition: menu_style.cpp:62
static style & default_style
Definition: menu.hpp:116
surf
Definition: filter.cpp:143
GPU_Rect GPU_SetClip(GPU_Target *target, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
Definition: SDL_gpu.c:1822
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
int font_size_
Definition: font.cpp:604
void scale_images(int max_width, int max_height)
Definition: menu_style.cpp:64
virtual ~style()
Definition: menu_style.cpp:48
GLint GLvoid * img
Definition: glew.h:1353
this module manages the cache of images.
Definition: image.cpp:75
int width() const
Definition: widget.cpp:134
virtual void draw_row(menu &menu_ref, const size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:879
friend class imgsel_style
Definition: menu.hpp:115
GLsizei const GLcharARB ** string
Definition: glew.h:4503
size_t get_cell_padding() const
Definition: menu_style.cpp:61
int height() const
Definition: widget.cpp:139
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu.cpp:804