The Battle for Wesnoth  1.15.0-dev
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/constants.hpp"
21 #include "image.hpp"
22 #include "lexical_cast.hpp"
23 #include "sdl/utils.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  normal_alpha_(0.2), selected_alpha_(0.6), heading_alpha_(0.3),
41  max_img_w_(-1), max_img_h_(-1)
42 {}
43 
45 {}
46 menu::imgsel_style::imgsel_style(const std::string &img_base, bool has_bg,
47  int normal_rgb, int selected_rgb, int heading_rgb,
48  double normal_alpha, double selected_alpha, double heading_alpha)
49  : img_base_(img_base), has_background_(has_bg), initialized_(false), load_failed_(false),
50  normal_rgb2_(normal_rgb), selected_rgb2_(selected_rgb), heading_rgb2_(heading_rgb),
51  normal_alpha2_(normal_alpha), selected_alpha2_(selected_alpha), heading_alpha2_(heading_alpha)
52 {}
54 {}
55 
56 std::size_t menu::style::get_font_size() const { return font_size_; }
57 std::size_t menu::style::get_cell_padding() const { return cell_padding_; }
58 std::size_t menu::style::get_thickness() const { return thickness_; }
59 
60 void menu::style::scale_images(int max_width, int max_height)
61 {
62  max_img_w_ = max_width;
63  max_img_h_ = max_height;
64 }
65 
67 {
68  surface surf = image::get_image(img_loc);
69  if(!surf.null())
70  {
71  int scale = 100;
72  if(max_img_w_ > 0 && surf->w > max_img_w_) {
73  scale = (max_img_w_ * 100) / surf->w;
74  }
75  if(max_img_h_ > 0 && surf->h > max_img_h_) {
76  scale = std::min<int>(scale, ((max_img_h_ * 100) / surf->h));
77  }
78  if(scale != 100)
79  {
80  return scale_surface(surf, (scale * surf->w)/100, (scale * surf->h)/100);
81  }
82  }
83  return surf;
84 }
85 
87 {
88  std::string path = img_base_ + "-" + img_sub + ".png";
89  const surface image = image::get_image(path);
90  img_map_[img_sub] = image;
91  return(!image.null());
92 }
93 
95 {
96  if(!initialized_)
97  {
98 
99  if( load_image("border-botleft")
100  && load_image("border-botright")
101  && load_image("border-topleft")
102  && load_image("border-topright")
103  && load_image("border-left")
104  && load_image("border-right")
105  && load_image("border-top")
106  && load_image("border-bottom") )
107  {
108  thickness_ = std::min(
109  img_map_["border-top"]->h,
110  img_map_["border-left"]->w);
111 
112 
113  if(has_background_ && !load_image("background"))
114  {
115  load_failed_ = true;
116  }
117  else
118  {
125 
126  load_failed_ = false;
127  }
128  initialized_ = true;
129  }
130  else
131  {
132  thickness_ = 0;
133  initialized_ = true;
134  load_failed_ = true;
135  }
136  }
137  return (!load_failed_);
138 }
139 
140 void menu::imgsel_style::draw_row_bg(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
141 {
142  if(type == SELECTED_ROW && has_background_ && !load_failed_) {
143  if(bg_cache_.width != rect.w || bg_cache_.height != rect.h)
144  {
145  //draw scaled background image
146  //scale image each time (to prevent loss of quality)
147  bg_cache_.surf = scale_surface(img_map_["background"], rect.w, rect.h);
148  bg_cache_.width = rect.w;
149  bg_cache_.height = rect.h;
150  }
151  SDL_Rect clip = rect;
152  menu_ref.video().blit_surface(rect.x,rect.y,bg_cache_.surf,nullptr,&clip);
153  }
154  else {
155  style::draw_row_bg(menu_ref, row_index, rect, type);
156  }
157 }
158 
159 void menu::imgsel_style::draw_row(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
160 {
161  if(!load_failed_) {
162  //draw item inside
163  style::draw_row(menu_ref, row_index, rect, type);
164 
165  if(type == SELECTED_ROW) {
166  // draw border
167  surface image;
168  SDL_Rect area;
169  SDL_Rect clip = rect;
170  area.x = rect.x;
171  area.y = rect.y;
172 
173  image = img_map_["border-top"];
174  area.x = rect.x;
175  area.y = rect.y;
176  do {
177  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
178  area.x += image->w;
179  } while( area.x < rect.x + rect.w );
180 
181  image = img_map_["border-left"];
182  area.x = rect.x;
183  area.y = rect.y;
184  do {
185  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
186  area.y += image->h;
187  } while( area.y < rect.y + rect.h );
188 
189  image = img_map_["border-right"];
190  area.x = rect.x + rect.w - thickness_;
191  area.y = rect.y;
192  do {
193  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
194  area.y += image->h;
195  } while( area.y < rect.y + rect.h );
196 
197  image = img_map_["border-bottom"];
198  area.x = rect.x;
199  area.y = rect.y + rect.h - thickness_;
200  do {
201  menu_ref.video().blit_surface(area.x,area.y,image,nullptr,&clip);
202  area.x += image->w;
203  } while( area.x < rect.x + rect.w );
204 
205  image = img_map_["border-topleft"];
206  area.x = rect.x;
207  area.y = rect.y;
208  menu_ref.video().blit_surface(area.x,area.y,image);
209 
210  image = img_map_["border-topright"];
211  area.x = rect.x + rect.w - image->w;
212  area.y = rect.y;
213  menu_ref.video().blit_surface(area.x,area.y,image);
214 
215  image = img_map_["border-botleft"];
216  area.x = rect.x;
217  area.y = rect.y + rect.h - image->h;
218  menu_ref.video().blit_surface(area.x,area.y,image);
219 
220  image = img_map_["border-botright"];
221  area.x = rect.x + rect.w - image->w;
222  area.y = rect.y + rect.h - image->h;
223  menu_ref.video().blit_surface(area.x,area.y,image);
224  }
225  }
226  else {
227  //default drawing
228  style::draw_row(menu_ref, row_index, rect, type);
229  }
230 }
231 
233 {
234  SDL_Rect bounds = style::item_size(item);
235 
236  bounds.w += 2 * thickness_;
237  bounds.h += 2 * thickness_;
238 
239  return bounds;
240 }
241 
242 
243 } //namesapce gui
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu_style.cpp:232
static style simple_style
Definition: menu.hpp:102
virtual void draw_row_bg(menu &menu_ref, const std::size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:140
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:1038
std::vector< char_t > string
std::size_t get_font_size() const
Definition: menu_style.cpp:56
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:46
int heading_rgb_
Definition: menu.hpp:55
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:273
Note: Specific to sdl_ttf.
int max_img_w_
Definition: menu.hpp:57
double heading_alpha_
Definition: menu.hpp:56
New lexcical_cast header.
ROW_TYPE
Definition: menu.hpp:32
int selected_rgb_
Definition: menu.hpp:55
General purpose widgets.
bool load_image(const std::string &img_sub)
Definition: menu_style.cpp:86
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu.cpp:793
#define h
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:112
double normal_alpha_
Definition: menu.hpp:56
-file util.hpp
static imgsel_style bluebg_style
Definition: menu.hpp:103
std::size_t cell_padding_
Definition: menu.hpp:52
bool null() const
Definition: surface.hpp:79
const int SIZE_NORMAL
Definition: constants.cpp:19
friend class style
Definition: menu.hpp:99
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
virtual void draw_row(menu &menu_ref, const std::size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:851
surface get_item_image(const image::locator &i_locator) const
Definition: menu_style.cpp:66
std::string path
Definition: game_config.cpp:57
static style & default_style
Definition: menu.hpp:101
double selected_alpha2_
Definition: menu.hpp:86
const std::string img_base_
Definition: menu.hpp:77
double selected_alpha_
Definition: menu.hpp:56
std::size_t get_cell_padding() const
Definition: menu_style.cpp:57
int w
int normal_rgb_
Definition: menu.hpp:55
double heading_alpha2_
Definition: menu.hpp:86
virtual void draw_row_bg(menu &menu_ref, const std::size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu.cpp:822
void scale_images(int max_width, int max_height)
Definition: menu_style.cpp:60
CVideo & video() const
Definition: widget.hpp:84
virtual ~style()
Definition: menu_style.cpp:44
std::map< std::string, surface > img_map_
Definition: menu.hpp:78
std::size_t thickness_
Definition: menu.hpp:53
virtual void draw_row(menu &menu_ref, const std::size_t row_index, const SDL_Rect &rect, ROW_TYPE type)
Definition: menu_style.cpp:159
std::size_t font_size_
Definition: menu.hpp:51
this module manages the cache of images.
Definition: image.cpp:102
int max_img_h_
Definition: menu.hpp:57
friend class imgsel_style
Definition: menu.hpp:100
bg_cache bg_cache_
Definition: menu.hpp:96
std::size_t get_thickness() const
Definition: menu_style.cpp:58