16 #define GETTEXT_DOMAIN "wesnoth-lib"
32 namespace minimum_selection
41 bool found_new_item =
false;
45 for(
unsigned i = ordered_index + 1;
i < item_count; ++
i) {
49 found_new_item =
true;
55 for(
signed i =
static_cast<signed>(ordered_index) - 1;
i >= 0; --
i) {
131 result.x += best_size.x;
133 if(best_size.y > result.y) {
134 result.y = best_size.y;
151 point current_origin = origin;
160 assert(best_size.y <=
size.y);
163 best_size.y =
size.y;
167 current_origin.x += best_size.x;
170 if(current_origin.x != origin.x +
size.x) {
171 ERR_GUI_L <<
"Failed to fit horizontal list to requested rect; expected right edge was " << origin.x +
size.x
172 <<
", actual right edge was " << current_origin.x
173 <<
" (left edge is " << origin.x <<
")\n";
179 point current_origin = origin;
343 if(best_size.x > result.x) {
344 result.x = best_size.x;
347 result.y += best_size.y;
363 point current_origin = origin;
371 assert(best_size.x <=
size.x);
374 best_size.x =
size.x;
378 current_origin.y += best_size.y;
381 if(current_origin.y != origin.y +
size.y) {
382 ERR_GUI_L <<
"Failed to fit vertical list to requested rect; expected bottom edge was " << origin.y +
size.y
383 <<
", actual bottom edge was " << current_origin.y
384 <<
" (top edge is " << origin.y <<
")\n";
390 point current_origin = origin;
554 std::size_t max_cols = std::sqrt(n_items) + 2;
556 std::vector<point> item_sizes;
557 for(std::size_t
i = 0;
i < n_items;
i++) {
563 if(item_sizes.empty()) {
567 std::vector<point> best_sizes(1);
569 best_sizes[0] = std::accumulate(item_sizes.begin(), item_sizes.end(),
point(),
573 int max_xtra = std::min_element(item_sizes.begin(), item_sizes.end(),
577 for(std::size_t cells_in_1st_row = 2; cells_in_1st_row <= max_cols; cells_in_1st_row++) {
578 int row_min_width = std::accumulate(item_sizes.begin(), item_sizes.begin() + cells_in_1st_row, 0,
579 [](
int a,
point b) { return a + b.x; }
582 int row_max_width = row_min_width + max_xtra;
584 point row_size, total_size;
586 for(std::size_t
n = 0;
n < item_sizes.size();
n++) {
587 if(row_size.x + item_sizes[
n].x > row_max_width) {
589 total_size.y += row_size.y;
591 if(total_size.x < row_size.x) {
592 total_size.x = row_size.x;
598 row_size.x += item_sizes[
n].x;
600 if(row_size.y < item_sizes[
n].y) {
601 row_size.y = item_sizes[
n].y;
605 total_size.y += row_size.y;
607 if(total_size.x < row_size.x) {
608 total_size.x = row_size.x;
611 best_sizes.push_back(total_size);
614 return *std::min_element(best_sizes.begin(), best_sizes.end(), [](
point p1,
point p2) {
616 std::max<double>(p1.x, p1.y) / std::min<double>(p1.x, p1.y) <
617 std::max<double>(p2.x, p2.y) / std::min<double>(p2.x, p2.y);
632 point current_origin = origin;
643 if(current_origin.x + best_size.x > origin.x +
size.x) {
644 current_origin.x = origin.x;
645 current_origin.y += row_height;
651 current_origin.x += best_size.x;
652 if(best_size.y > row_height) {
653 row_height = best_size.y;
660 if(current_origin.y + row_height != origin.y +
size.y) {
662 better_size.y -= current_origin.y + row_height - origin.y;
669 point current_origin = origin;
670 std::size_t row_height = 0;
678 current_origin.x = origin.x;
679 current_origin.y += row_height;
920 if(best_size.x > result.x) {
921 result.x = best_size.x;
924 if(best_size.y > result.y) {
925 result.y = best_size.y;
959 if(selected_item < 0) {
972 if(selected_item < 0) {
1024 namespace select_action
1030 VALIDATE(selectable,
"Only toggle buttons and panels are allowed as the cells of a list definition.");
1037 const std::function<
void(
widget&)>& callback)
1039 for(
unsigned row = 0; row <
g->get_rows(); ++row) {
1040 for(
unsigned col = 0; col <
g->get_cols(); ++col) {
1051 widget_data::const_iterator itor =
data.find(btn->
id());
1053 if(itor ==
data.end()) {
1054 itor =
data.find(
"");
1056 if(itor !=
data.end()) {
1063 }
else if(child_grid) {
1066 FAIL(
"Only toggle buttons and panels are allowed as the cells of a list definition.");
1074 const std::function<
void(
widget&)>& callback)
1079 if(
item.first.empty()) {
1083 control->set_members(
item.second);
1102 #ifdef GENERATE_PLACEMENT
1103 static_assert(
false,
"GUI2/Generator: GENERATE_PLACEMENT already defined!");
1105 #define GENERATE_PLACEMENT \
1106 switch(placement) { \
1107 case generator_base::horizontal_list: \
1108 result = std::make_unique<generator<minimum, maximum, policy::placement::horizontal_list, select_action>>(); \
1110 case generator_base::vertical_list: \
1111 result = std::make_unique<generator<minimum, maximum, policy::placement::vertical_list, select_action>>(); \
1113 case generator_base::table: \
1114 result = std::make_unique<generator<minimum, maximum, policy::placement::table, select_action>>(); \
1116 case generator_base::independent: \
1117 result = std::make_unique<generator<minimum, maximum, policy::placement::independent, select_action>>(); \
1124 #ifdef GENERATE_SELECT
1125 static_assert(
false,
"GUI2/Generator: GENERATE_SELECT already defined!");
1127 #define GENERATE_SELECT \
1129 typedef policy::select_action::selection select_action; \
1130 GENERATE_PLACEMENT \
1132 typedef policy::select_action::show select_action; \
1133 GENERATE_PLACEMENT \
1137 #ifdef GENERATE_MAXIMUM
1138 static_assert(
false,
"GUI2/Generator: GENERATE_MAXIMUM already defined!");
1140 #define GENERATE_MAXIMUM \
1142 typedef policy::maximum_selection::one_item maximum; \
1145 typedef policy::maximum_selection::many_items maximum; \
1150 #ifdef GENERATE_BODY
1151 static_assert(
false,
"GUI2/Generator: GENERATE_BODY already defined!");
1153 #define GENERATE_BODY \
1155 typedef policy::minimum_selection::one_item minimum; \
1158 typedef policy::minimum_selection::no_item minimum; \
1164 const bool has_minimum,
const bool has_maximum,
const placement placement,
const bool select)
1166 std::unique_ptr<generator_base> result =
nullptr;
1203 < policy::minimum_selection::one_item
1204 , policy::maximum_selection::one_item
1205 , policy::placement::vertical_list
1206 , policy::select_action::selection
1210 < policy::minimum_selection::one_item
1211 , policy::maximum_selection::many_items
1212 , policy::placement::vertical_list
1213 , policy::select_action::selection
1217 < policy::minimum_selection::no_item
1218 , policy::maximum_selection::one_item
1219 , policy::placement::vertical_list
1220 , policy::select_action::selection
1224 < policy::minimum_selection::no_item
1225 , policy::maximum_selection::many_items
1226 , policy::placement::vertical_list
1227 , policy::select_action::selection
Abstract base class for the generator.
virtual unsigned get_ordered_index(unsigned index) const =0
If a sort-order is being applied, maps from unsorted to sorted indicies.
virtual unsigned get_selected_item_count() const =0
Returns the number of selected items.
virtual grid & item_ordered(const unsigned index)=0
Gets the grid of an item.
virtual void select_item(const unsigned index, const bool select)=0
(De)selects an item.
virtual grid & item(const unsigned index)=0
Gets the grid of an item.
virtual unsigned get_item_count() const =0
Returns the number of items.
static std::unique_ptr< generator_base > build(const bool has_minimum, const bool has_maximum, const placement placement, const bool select)
Create a new generator.
virtual bool is_selected(const unsigned index) const =0
Returns whether the item is selected.
virtual bool get_item_shown(const unsigned index) const =0
Returns whether the item is shown.
placement
Determines how the items are placed.
virtual unsigned get_item_at_ordered(unsigned index_ordered) const =0
If a sort-order is being applied, maps from sorted to unsorted indicies.
virtual void do_select_item(const unsigned index)=0
Selects a not selected item.
virtual void do_deselect_item(const unsigned index)=0
Deselects a selected item.
virtual int get_selected_item() const =0
Returns the selected item.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See widget::set_visible_rectangle.
const widget * get_widget(const unsigned row, const unsigned col) const
Returns the widget in the selected cell.
unsigned int get_rows() const
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
unsigned int get_cols() const
virtual void set_origin(const point &origin) override
See widget::set_origin.
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
A panel is a visible container to hold multiple widgets.
Small abstract helper class.
virtual void set_value(unsigned value, bool fire_event=false)=0
Select the styled_widget.
Class for a toggle button.
void point(int x, int y)
Draw a single point.
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
std::map< std::string, widget_item > widget_data
rng * generator
This generator is automatically synced during synced context.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
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::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
void set_item_shown(const unsigned index, const bool show)
See minimum_selection::one_item::set_item_shown().
void delete_item(const unsigned index)
Called just before an item is deleted.
bool deselect_item(const unsigned index)
Called when the users wants to deselect an item.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
void set_item_shown(const unsigned index, const bool show)
Called when an item is shown or hidden.
virtual void set_origin(const point &origin) override
See widget::set_origin.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
void handle_key_left_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from generator_base.
void handle_key_right_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from generator_base.
virtual void place(const point &origin, const point &size) override
See widget::place.
bool placed_
Has the grid already been placed?
void set_visible_rectangle(const SDL_Rect &rectangle) override
Sets the visible rectangle of the generator.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
void set_visible_rectangle(const SDL_Rect &rectangle) override
See horizontal_list::set_visible_rectangle().
virtual void request_reduce_height(const unsigned maximum_height) override
See horizontal_list::request_reduce_height.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
virtual void set_origin(const point &origin) override
See widget::set_origin.
virtual void place(const point &, const point &) override
See widget::place.
bool placed_
Has the grid already been placed?
void handle_key_up_arrow(SDL_Keymod, bool &) override
Inherited from generator_base.
void handle_key_right_arrow(SDL_Keymod, bool &) override
Inherited from generator_base.
virtual void set_origin(const point &) override
See widget::set_origin.
void handle_key_down_arrow(SDL_Keymod, bool &) override
Inherited from generator_base.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
void handle_key_left_arrow(SDL_Keymod, bool &) override
Inherited from generator_base.
virtual widget * find_at(const point &, const bool) override
See widget::find_at.
void set_visible_rectangle(const SDL_Rect &) override
See horizontal_list::set_visible_rectangle().
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
virtual void set_origin(const point &origin) override
See widget::set_origin.
void handle_key_up_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from generator_base.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
virtual void place(const point &origin, const point &size) override
See widget::place.
bool placed_
Has the grid already been placed?
void set_visible_rectangle(const SDL_Rect &rectangle) override
See horizontal_list::set_visible_rectangle().
virtual point calculate_best_size() const override
See widget::calculate_best_size.
void handle_key_down_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from generator_base.
void init(grid *grid, const widget_data &data, const std::function< void(widget &)> &callback)
Helper function to initialize a grid.
void select(grid &grid, const bool select)
void init(grid *grid, const widget_data &data, const std::function< void(widget &)> &callback)
Helper function to initialize a grid.
static map_location::DIRECTION n
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE(cond, message)
The macro to use for the validation of WML.