16 #define GETTEXT_DOMAIN "wesnoth-lib"
50 alpha_sort_.insert(column);
56 numeric_sort_.insert(column);
62 id_sort_.insert(column);
69 redirect_sort_.emplace(column, to);
77 pos_sort_[column] = pos;
83 const std::map<int,int>::const_iterator
redirect = redirect_sort_.find(column);
84 if(
redirect != redirect_sort_.end()) {
85 return column_sortable(
redirect->second);
88 return alpha_sort_.count(column) == 1 || numeric_sort_.count(column) == 1 ||
89 pos_sort_.count(column) == 1 || id_sort_.count(column) == 1;
94 const std::map<int,int>::const_iterator
redirect = redirect_sort_.find(column);
95 if(
redirect != redirect_sort_.end()) {
96 return less(
redirect->second,row1,row2);
99 if(id_sort_.count(column) == 1) {
100 return row1.
id < row2.
id;
103 if(column < 0 || column >=
int(row2.
fields.size())) {
107 if(column >=
int(row1.
fields.size())) {
111 const std::string& item1 = row1.
fields[column];
112 const std::string& item2 = row2.
fields[column];
114 if(alpha_sort_.count(column) == 1) {
115 std::string::const_iterator begin1 = item1.begin(), end1 = item1.end(),
116 begin2 = item2.begin(), end2 = item2.end();
126 }
else if(numeric_sort_.count(column) == 1) {
127 int val_1 = lexical_cast_default<int>(item1, 0);
128 int val_2 = lexical_cast_default<int>(item2, 0);
130 return val_1 > val_2;
133 const std::map<int,std::vector<int>>::const_iterator itor = pos_sort_.find(column);
134 if(itor != pos_sort_.end()) {
135 const std::vector<int>& pos = itor->second;
136 if(row1.
id >= pos.size()) {
140 if(row2.
id >= pos.size()) {
144 return pos[row1.
id] < pos[row2.
id];
151 bool click_selects,
int max_height,
int max_width,
152 const sorter* sorter_obj,
style *menu_style,
const bool auto_join)
176 for(std::vector<std::string>::const_iterator itor =
items.begin();
177 itor !=
items.end(); ++itor) {
184 const std::size_t
id =
items_.size();
187 items_.push_back(new_item);
190 if(
items_.back().fields.empty()) {
191 items_.back().fields.push_back(
" ");
196 std::string& first_item =
items_.back().fields.front();
197 if(first_item.empty() ==
false && first_item[0] ==
DEFAULT_ITEM) {
199 first_item.erase(first_item.begin());
214 sort_func(
const menu::sorter& pred,
int column) : pred_(&pred), column_(column)
219 return pred_->less(column_,
a,
b);
223 const menu::sorter* pred_;
243 if(selectid >= 0 && selectid <
int(
item_pos_.size())) {
252 std::size_t sz =
items_.size();
254 for(std::size_t
i = 0;
i != sz; ++
i)
261 std::size_t sz =
items_.size();
263 for(std::size_t
n = 0;
n != sz; ++
n) {
288 int w = std::accumulate(widths.begin(), widths.end(), 0);
318 if(pos1 < 0 || pos1 >=
int(
item_pos_.size()) ||
329 std::size_t nb_items =
items_.size();
330 if (
index >= nb_items)
340 for(std::size_t
i = 0;
i != nb_items; ++
i) {
343 if (n2 >
index) --n2;
386 }
else if(scrolled_to_max) {
420 const std::size_t max_height = (
426 std::vector<int> heights;
432 std::sort(heights.begin(),heights.end(),std::greater<int>());
434 for(
n = 0;
n !=
items_.size() && sum < max_height; ++
n) {
438 if(sum > max_height &&
n > 1)
453 if (new_selected >=
items_.size())
456 bool changed =
false;
466 if(!
silent_ && !silent && changed) {
479 std::size_t nb_items =
items_.size();
551 if(event ==
nullptr) {
556 if(event->type == SDL_KEYDOWN) {
557 SDL_Keycode key =
event->key.keysym.sym;
585 if(event.type == SDL_KEYDOWN) {
589 }
else if(!
mouse_locked() && ((event.type == SDL_MOUSEBUTTONDOWN &&
590 (event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT)) ||
595 if(event.type == SDL_MOUSEBUTTONDOWN) {
599 x =
reinterpret_cast<std::size_t
>(
event.user.data1);
600 y =
reinterpret_cast<std::size_t
>(
event.user.data2);
642 }
else if(!
mouse_locked() && event.type == SDL_MOUSEMOTION) {
644 const int item =
hit(event.motion.x,event.motion.y);
645 const bool out = (
item == -1);
655 const int heading_item =
hit_heading(event.motion.x,event.motion.y);
709 const bool already_sorted = (column ==
sortby_);
729 SDL_Rect res {0,0,0,0};
731 for (std::vector<std::string>::const_iterator it = img_text_items.begin();
732 it != img_text_items.end(); ++it) {
733 if (res.w > 0 || res.h > 0) {
737 const std::string str = *it;
739 const std::string image_name(str.begin()+1,str.end());
741 if (image_size.x && image_size.y) {
742 int w = image_size.x;
743 int h = image_size.y;
746 res.h = std::max<int>(
h, res.h);
750 const SDL_Rect area {0,0,10000,10000};
751 const SDL_Rect font_size =
754 res.w += font_size.w;
755 res.h = std::max<int>(font_size.h, res.h);
769 alpha = normal_alpha_;
773 alpha = selected_alpha_;
777 alpha = heading_alpha_;
782 color_t c((rgb & 0xff0000) >> 16, (rgb & 0xff00) >> 8, rgb & 0xff);
793 draw_row_bg(menu_ref, row_index,
rect,
type);
795 SDL_Rect minirect =
rect;
797 minirect.x += thickness_;
798 minirect.y += thickness_;
799 minirect.w -= 2*thickness_;
800 minirect.h -= 2*thickness_;
809 for(std::size_t col = 0; col != row.size(); ++col) {
813 if(col == widths.size()) {
814 widths.push_back(res.w + text_trailing_space);
815 }
else if(
static_cast<std::size_t
>(res.w) > widths[col] - text_trailing_space) {
816 widths[col] = res.w + text_trailing_space;
824 pos = (pos == std::string::npos) ? 0 : pos+1;
832 for(std::size_t row = 0; row !=
items_.size(); ++row) {
856 int dir = (lang_rtl) ? -1 : 1;
863 for(std::size_t
i = 0;
i != row.size(); ++
i) {
869 rect draw_rect {xpos, loc.y, widths[
i], loc.h };
878 const int last_x = xpos;
879 column.w = widths[
i];
880 std::string str = row[
i];
882 for (std::vector<std::string>::const_iterator it = img_text_items.begin();
883 it != img_text_items.end(); ++it) {
886 const std::string image_name(str.begin()+1,str.end());
891 const int remaining_width =
max_width_ < 0 ? area.w :
892 std::min<int>(
max_width_, ((lang_rtl)? xpos - loc.x : loc.x + loc.w - xpos));
893 if(img && img_w <= remaining_width
894 && loc.y + img_h < area.h) {
895 const std::size_t
y = loc.y + (loc.h - img_h)/2;
896 const std::size_t
w = img_w + 5;
897 const std::size_t
x = xpos + ((lang_rtl) ? widths[
i] -
w : 0);
907 const std::size_t
y = loc.y + (loc.h - text_size.second)/2;
908 const std::size_t padding = 2;
909 rect text_loc = column;
911 text_loc.h = text_size.second;
918 :
"buttons/sliders/slider_arrow_blue.png~ROTATE(180)"}));
919 if(sort_tex && sort_tex.
w() <= widths[
i] && sort_tex.
h() <= loc.h) {
920 const int sort_x = xpos + widths[
i] - sort_tex.
w() - padding;
921 const int sort_y = loc.y + loc.h/2 - sort_tex.
h()/2;
922 SDL_Rect dest = {sort_x, sort_y, sort_tex.
w(), sort_tex.
h()};
927 xpos += dir * (text_size.first + 5);
933 xpos = last_x + widths[
i];
952 if (
x >= loc.x && x < loc.x + loc.w && y >= loc.y &&
y < loc.y + loc.h) {
953 for(std::size_t
i = 0;
i !=
items_.size(); ++
i) {
966 int j = -1, j_end = widths.size();
979 if(
y >= loc.y &&
static_cast<std::size_t
>(
y) < loc.y +
height) {
994 if (
item < first_item_on_screen ||
999 const std::map<int,SDL_Rect>::const_iterator
i =
itemRects_.find(
item);
1006 if (
item != first_item_on_screen) {
1015 if(res.x > canvas_size.x) {
1017 }
else if(res.x + res.w > canvas_size.x) {
1018 res.w = canvas_size.x - res.x;
1021 if(res.y > canvas_size.y) {
1023 }
else if(res.y + res.h > canvas_size.y) {
1024 res.h = canvas_size.y - res.y;
1029 if (loc.x > 0 && loc.y > 0)
1037 std::size_t res = 0;
1038 for(std::vector<std::string>::const_iterator
i =
item.begin();
i !=
item.end(); ++
i) {
1040 res = std::max<int>(
rect.h,res);
1060 std::size_t max_height = 0;
1061 for(std::size_t
n = 0;
n !=
items_.size(); ++
n) {
1070 if(
id >=
items_.size()) {
1079 if(pos >=
items_.size()) {
Generic locator abstracting the location of an image.
Wrapper class to encapsulate creation and management of an SDL_Texture.
int w() const
The draw-space width of the texture, in pixels.
int h() const
The draw-space height of the texture, in pixels.
Drawing functions, for drawing things on the screen.
#define DOUBLE_CLICK_EVENT
bool current_language_rtl()
New lexcical_cast header.
void fill(const SDL_Rect &rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Fill an area with the given colour.
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
void rect(const SDL_Rect &rect)
Draw a rectangle.
rect pango_draw_text(bool actually_draw, const rect &area, int size, const color_t &color, const std::string &text, int x, int y, bool use_tooltips, pango_text::FONT_STYLE style)
Draws text on the screen.
std::pair< int, int > pango_line_size(const std::string &line, int font_size, font::pango_text::FONT_STYLE font_style)
Determine the width and height of a line of text given a certain font size.
const color_t NORMAL_COLOR
const std::string menu_select
const std::string button_press
std::pair< std::string, unsigned > item
texture get_texture(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image texture suitable for hardware-accelerated rendering.
point get_size(const locator &i_locator, bool skip_cache)
Returns the width and height of an image.
const std::vector< std::string > items
constexpr const SDL_Rect empty_rect
void play_UI_sound(const std::string &files)
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.
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...
bool chars_less_insensitive(char a, char b)
std::vector< std::string > split(const config_attribute_value &val)
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
rect game_canvas()
The game canvas area, in drawing coordinates.
Contains the SDL_Rect helper code.
Transitional API for porting SDL_ttf-based code to Pango.
The basic class for representing 8-bit RGB or RGBA colour values.
An abstract description of a rectangle with integer coordinates.
static map_location::DIRECTION n
static map_location::DIRECTION s
char const IMG_TEXT_SEPARATOR
char const HEADING_PREFIX
char const COLUMN_SEPARATOR
bool is_wml_separator(char c)