15 #define GETTEXT_DOMAIN "wesnoth-lib" 108 std::vector<std::string> parts =
utils::split(s,
'/', 0);
110 int num = lexical_cast_default<int>(parts[0], 0);
111 int denom = lexical_cast_default<int>(parts[1], 0);
112 return std::make_pair(num, denom);
119 if(xp_frac.second == 0)
120 xp_frac.second = 1000000;
122 return xp_frac.second - xp_frac.first;
129 return less(redirect->second,row1,row2);
133 return row1.
id < row2.
id;
136 if(column < 0 || column >=
int(row2.
fields.size())) {
140 if(column >=
int(row1.
fields.size())) {
148 std::string::const_iterator begin1 = item1.begin(), end1 = item1.end(),
149 begin2 = item2.begin(), end2 = item2.end();
160 int val_1 = lexical_cast_default<int>(item1, 0);
161 int val_2 = lexical_cast_default<int>(item2, 0);
163 return val_1 > val_2;
164 }
else if(
xp_sort_.count(column) == 1) {
167 int level_1 = lexical_cast_default<int>(item1, 0);
168 int level_2 = lexical_cast_default<int>(item2, 0);
169 if (level_1 == level_2) {
175 return level_1 > level_2;
178 const std::map<int,std::vector<int>>::const_iterator itor =
pos_sort_.find(column);
180 const std::vector<int>& pos = itor->second;
181 if(row1.
id >= pos.size()) {
185 if(row2.
id >= pos.size()) {
189 return pos[row1.
id] < pos[row2.
id];
196 bool click_selects,
int max_height,
int max_width,
197 const sorter* sorter_obj,
style *menu_style,
const bool auto_join)
222 for(std::vector<std::string>::const_iterator itor = items.begin();
223 itor != items.end(); ++itor) {
230 const std::size_t
id =
items_.size();
233 items_.push_back(new_item);
236 if(
items_.back().fields.empty()) {
237 items_.back().fields.push_back(
" ");
242 std::string& first_item =
items_.back().fields.front();
243 if(first_item.empty() ==
false && first_item[0] ==
DEFAULT_ITEM) {
245 first_item.erase(first_item.begin());
262 sort_func(
const menu::sorter& pred,
int column) : pred_(&pred), column_(column)
267 return pred_->less(column_,a,b);
291 if(selectid >= 0 && selectid <
int(
item_pos_.size())) {
300 std::size_t sz =
items_.size();
302 for(std::size_t
i = 0;
i != sz; ++
i)
309 std::size_t sz =
items_.size();
311 for(std::size_t
n = 0;
n != sz; ++
n) {
322 i->help.emplace_back();
325 if(items.size() >= 2) {
327 i->help.push_back(items.back());
329 i->help.emplace_back();
349 h = std::max(h,
height());
356 int w = std::accumulate(widths.begin(), widths.end(), 0);
359 w = std::max(w,
width());
387 if(pos1 < 0 || pos1 >=
int(
item_pos_.size()) ||
398 std::size_t nb_items =
items_.size();
399 if (index >= nb_items)
409 for(std::size_t
i = 0;
i != nb_items; ++
i) {
412 if (n2 > index) --n2;
448 if (!keep_viewport ||
selected_ >= items.size()) {
455 }
else if(scrolled_to_max) {
491 std::vector<int> heights;
493 for(n = 0; n !=
items_.size(); ++
n) {
497 std::sort(heights.begin(),heights.end(),std::greater<int>());
499 for(n = 0; n !=
items_.size() && sum < max_height; ++
n) {
503 if(sum > max_height && n > 1)
518 if (new_selected >=
items_.size())
521 bool changed =
false;
531 if(!
silent_ && !silent && changed) {
544 std::size_t nb_items =
items_.size();
616 if(event ==
nullptr) {
621 if(event->type == SDL_KEYDOWN) {
622 SDL_Keycode key =
event->key.keysym.sym;
650 if(event.type == SDL_KEYDOWN) {
654 }
else if(!
mouse_locked() && ((event.type == SDL_MOUSEBUTTONDOWN &&
655 (event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT)) ||
660 if(event.type == SDL_MOUSEBUTTONDOWN) {
664 x =
reinterpret_cast<std::size_t
>(
event.user.data1);
665 y =
reinterpret_cast<std::size_t
>(
event.user.data2);
707 }
else if(!
mouse_locked() && event.type == SDL_MOUSEMOTION) {
709 const int item =
hit(event.motion.x,event.motion.y);
710 const bool out = (item == -1);
720 const int heading_item =
hit_heading(event.motion.x,event.motion.y);
774 const bool already_sorted = (column ==
sortby_);
794 SDL_Rect res {0,0,0,0};
796 for (std::vector<std::string>::const_iterator it = img_text_items.begin();
797 it != img_text_items.end(); ++it) {
798 if (res.w > 0 || res.h > 0) {
802 const std::string str = *it;
804 const std::string image_name(str.begin()+1,str.end());
805 surface const img = get_item_image(image_name);
808 res.h = std::max<int>(img->h, res.h);
812 const SDL_Rect area {0,0,10000,10000};
815 res.w += font_size.w;
816 res.h = std::max<int>(font_size.h, res.h);
832 alpha = normal_alpha_;
836 alpha = selected_alpha_;
840 alpha = heading_alpha_;
845 color_t c((rgb & 0xff0000) >> 16, (rgb & 0xff00) >> 8, rgb & 0xff);
853 if(rect.w == 0 || rect.h == 0) {
856 draw_row_bg(menu_ref, row_index, rect, type);
858 SDL_Rect minirect = rect;
860 minirect.x += thickness_;
861 minirect.y += thickness_;
862 minirect.w -= 2*thickness_;
863 minirect.h -= 2*thickness_;
865 menu_ref.
draw_row(row_index, minirect, type);
872 for(std::size_t col = 0; col != row.size(); ++col) {
876 if(col == widths.size()) {
877 widths.push_back(res.w + text_trailing_space);
878 }
else if(static_cast<std::size_t>(res.w) > widths[col] - text_trailing_space) {
879 widths[col] = res.w + text_trailing_space;
887 pos = (pos == std::string::npos) ? 0 : pos+1;
888 return(item.size() > pos && item.at(pos) ==
IMAGE_PREFIX);
895 for(std::size_t row = 0; row !=
items_.size(); ++row) {
919 int dir = (lang_rtl) ? -1 : 1;
920 SDL_Rect column = loc;
925 for(std::size_t
i = 0;
i != row.size(); ++
i) {
944 const int last_x = xpos;
945 column.w = widths[
i];
946 std::string str = row[
i];
948 for (std::vector<std::string>::const_iterator it = img_text_items.begin();
949 it != img_text_items.end(); ++it) {
952 const std::string image_name(str.begin()+1,str.end());
954 const int remaining_width =
max_width_ < 0 ? area.w :
955 std::min<int>(
max_width_, ((lang_rtl)? xpos - rect.x : rect.x + rect.w - xpos));
956 if(img !=
nullptr && img->w <= remaining_width
957 && rect.y + img->h < area.h) {
958 const std::size_t
y = rect.y + (rect.h - img->h)/2;
959 const std::size_t
w = img->w + 5;
960 const std::size_t
x = xpos + ((lang_rtl) ? widths[
i] - w : 0);
968 const bool has_wrap = (str.find_first_of(
"\r\n") != std::string::npos);
970 std::string to_show = str;
974 int style = TTF_STYLE_NORMAL;
976 std::string::const_iterator it2_beg = to_show.begin(), it2_end = to_show.end(),
978 if (it2 != it2_end) {
979 std::string tmp(it2, it2_end);
980 to_show.erase(it2 - it2_beg, it2_end - it2_beg);
985 const std::size_t
y = rect.y + (rect.h - text_size.h)/2;
986 const std::size_t padding = 2;
992 "buttons/sliders/slider_arrow_blue.png~ROTATE(180)");
993 if(sort_img !=
nullptr && sort_img->w <= widths[
i] && sort_img->h <= rect.h) {
994 const std::size_t sort_x = xpos + widths[
i] - sort_img->w - padding;
995 const std::size_t sort_y = rect.y + rect.h/2 - sort_img->h/2;
1000 xpos += dir * (text_size.w + 5);
1006 xpos = last_x + widths[
i];
1036 }
else if(*
i >= 0 && *
i <
int(
item_pos_.size())) {
1064 if (x >= loc.x && x < loc.x + loc.w && y >= loc.y && y < loc.y + loc.h) {
1065 for(std::size_t
i = 0;
i !=
items_.size(); ++
i) {
1067 if (y >= rect.y && y < rect.y + rect.h)
1078 int j = -1, j_end = widths.size();
1079 for(x -=
location().x; x >= 0; x -= widths[j]) {
1089 const int row =
hit(x, y);
1091 return std::pair<int,int>(-1, -1);
1096 return std::pair<int,int>(-1, -1);
1099 return std::pair<int,int>(
x,
y);
1106 if(y >= loc.y && static_cast<std::size_t>(y) < loc.y + height) {
1121 if (item < first_item_on_screen ||
1126 const std::map<int,SDL_Rect>::const_iterator
i =
itemRects_.find(item);
1133 if (item != first_item_on_screen) {
1135 y = prev.y + prev.h;
1142 if(res.x > screen_area.w) {
1144 }
else if(res.x + res.w > screen_area.w) {
1145 res.w = screen_area.w - res.x;
1148 if(res.y > screen_area.h) {
1150 }
else if(res.y + res.h > screen_area.h) {
1151 res.h = screen_area.h - res.y;
1156 if (loc.x > 0 && loc.y > 0)
1164 std::size_t res = 0;
1165 for(std::vector<std::string>::const_iterator
i = item.begin();
i != item.end(); ++
i) {
1167 res = std::max<int>(rect.h,res);
1187 std::size_t max_height = 0;
1188 for(std::size_t
n = 0;
n !=
items_.size(); ++
n) {
1199 const std::pair<int,int> loc(
hit(mousex,mousey),
hit_column(mousex));
1202 }
else if(loc.first == -1) {
1210 if(std::size_t(loc.first) <
items_.size()) {
1211 const std::vector<std::string>& row =
items_[
item_pos_[loc.first]].help;
1212 if(std::size_t(loc.second) < row.size()) {
1213 const std::string&
help = row[loc.second];
1214 if(help.empty() ==
false) {
1227 if(
id >=
items_.size()) {
1236 if(pos >=
items_.size()) {
SDL_Rect text_area(const std::string &text, int size, int style)
Calculate the size of a text (in pixels) if it were to be drawn.
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
char const IMG_TEXT_SEPARATOR
static std::pair< int, int > parse_fraction(const std::string &s)
std::string::const_iterator parse_markup(std::string::const_iterator i1, std::string::const_iterator i2, int *font_size, color_t *color, int *style)
Parses the markup-tags at the front of a string.
const std::string menu_select
const std::vector< std::string > items
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.
static int xp_to_advance(const std::string &s)
bool chars_less_insensitive(char a, char b)
char const HELP_STRING_SEPARATOR
bool current_language_rtl()
const color_t NORMAL_COLOR
#define DOUBLE_CLICK_EVENT
bool is_wml_separator(char c)
static map_location::DIRECTION s
std::vector< std::string > quoted_split(const std::string &val, char c, int flags, char quote)
This function is identical to split(), except it does not split when it otherwise would if the previo...
int get_height(bool as_pixels=true) const
Returns the window renderer height in pixels or in screen coordinates.
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
static int sort(lua_State *L)
int set_help_string(const std::string &str)
Displays a help string with the given text.
std::string make_text_ellipsis(const std::string &text, int font_size, int max_width, int style)
If the text exceeds the specified max width, end it with an ellipsis (...)
const std::string button_press
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an SDL_Rect with the given dimensions.
char const HEADING_PREFIX
Contains the SDL_Rect helper code.
char const COLUMN_SEPARATOR
std::string del_tags(const std::string &text)
Copy string, but without tags at the beginning.
constexpr const SDL_Rect empty_rect
std::vector< std::string > split(const config_attribute_value &val)
SDL_Rect draw_text(surface &dst, const SDL_Rect &area, int size, const color_t &color, const std::string &txt, int x, int y, bool use_tooltips, int style)
Function to draw text on a surface.
void play_UI_sound(const std::string &files)
void fill_rectangle(const SDL_Rect &rect, const color_t &color)
Draws a filled rectangle.
static void reverse(lua_State *L, StkId from, StkId to)
SDL_Rect screen_area(bool as_pixels=true) const
Returns the current window renderer area, either in pixels or screen coordinates. ...
static map_location::DIRECTION n
std::string::const_iterator iterator
void clear_help_string(int handle)
Removes the help string with the given handle.