16 #define GETTEXT_DOMAIN "wesnoth-lib"
35 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
36 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
49 , placement_(builder.placement)
50 , list_builder_(builder.list_builder)
52 , callback_order_change_()
54 const auto conf = cast_config_to<listbox_definition>();
60 if(
auto header = builder.header) {
61 header->id =
"_header_grid";
62 replacements.try_emplace(
"_header_grid_placeholder", std::move(header));
65 if(
auto footer = builder.footer) {
66 footer->id =
"_footer_grid";
67 replacements.try_emplace(
"_footer_grid_placeholder", std::move(footer));
70 conf->grid->build(get_grid(), replacements);
79 builder.allow_selection);
124 int height_reduced = 0;
125 int width_reduced = 0;
132 int row_pos_x = is_horizontal ? -1 : 0;
134 for(; count; --count) {
146 if((height_reduced != 0 || width_reduced != 0) &&
get_item_count() != 0) {
147 resize_content(-width_reduced, -height_reduced, row_pos_x, row_pos_y);
180 bool resize_needed =
false;
221 bool resize_needed =
false;
227 for(std::size_t
i = 0;
i < shown.size(); ++
i) {
251 boost::dynamic_bitset<> mask;
254 for(std::size_t
i = 0;
i < mask.size(); ++
i) {
283 throw std::invalid_argument(
"invalid listbox index");
322 if(checkbox !=
nullptr) {
342 if(selected_item == -1) {
383 utils::optional<unsigned> vertical_scrollbar_position, horizontal_scrollbar_position;
395 if(vertical_scrollbar_position && horizontal_scrollbar_position) {
400 }
else if(selected_item != -1) {
414 const int height_modification,
415 const int width_modification_pos,
416 const int height_modification_pos)
419 << width_modification <<
" height_modification " << height_modification <<
".";
422 width_modification, height_modification, width_modification_pos, height_modification_pos))
426 size.x += width_modification;
427 size.y += height_modification;
434 if(width_modification < 0 || height_modification < 0) {
456 if(
size.x < content.x) {
470 if(
const grid* header =
get_grid().find_widget<const grid>(
"_header_grid",
false,
false)) {
472 result.y += header->get_best_size().y;
476 if(
const grid* footer =
get_grid().find_widget<const grid>(
"_footer_grid",
false,
false)) {
478 result.y += footer->get_best_size().y;
564 auto header = find_widget<grid>(
"_header_grid",
false,
false);
570 const std::size_t
i =
orders_.size();
571 orders_.emplace_back(toggle, std::move(array));
583 if(
w &&
w != &selectable) {
589 if(
static_cast<unsigned>(order) >
orders_[column].second.size()) {
593 if(order == sort_order::type::none) {
624 if(!
w ||
dynamic_cast<widget*
>(
w)->
id() !=
id)
continue;
641 if(sort != sort_order::type::none) {
642 return {
dynamic_cast<widget*
>(
w), sort };
646 return {
nullptr, sort_order::type::none };
694 load_resolutions<resolution>(cfg);
706 grid = std::make_shared<builder_grid>(child);
713 std::vector<widget_data> list_data;
715 for(
const auto& row :
data.child_range(
"row")) {
716 auto cols = row.child_range(
"column");
718 VALIDATE(
static_cast<unsigned>(cols.size()) == req_cols,
719 _(
"‘list_data’ must have the same number of columns as the ‘list_definition’.")
722 for(
const auto&
c : cols) {
723 list_data.emplace_back();
725 for(
const auto& [key, value] :
c.attribute_range()) {
726 list_data.back()[
""][key] = value;
729 for(
const auto&
w :
c.child_range(
"widget")) {
732 for(
const auto& [key, value] :
w.attribute_range()) {
733 list_data.back()[
w[
"id"]][key] = value;
744 , placement(placement)
747 , list_builder(nullptr)
749 , has_minimum(cfg[
"has_minimum"].to_bool(true))
750 , has_maximum(cfg[
"has_maximum"].to_bool(true))
751 , allow_selection(cfg[
"allow_selection"].to_bool(true))
769 auto widget = std::make_unique<listbox>(*
this);
770 DBG_GUI_G <<
"Window builder: placed listbox '" <<
id <<
"' with definition '" <<
definition <<
"'.";
778 header = std::make_shared<builder_grid>(*
h);
782 footer = std::make_shared<builder_grid>(*
f);
A config object defines a single node in a WML file, with access to child nodes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
const grid & get_grid() const
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Abstract base class for the generator.
std::function< bool(unsigned, unsigned)> order_func
virtual void set_order(const order_func &order)=0
virtual void handle_key_left_arrow(SDL_Keymod modifier, bool &handled)=0
Left arrow key pressed.
virtual unsigned get_selected_item_count() const =0
Returns the number of selected items.
virtual void handle_key_right_arrow(SDL_Keymod modifier, bool &handled)=0
Right arrow key pressed.
virtual void set_item_shown(const unsigned index, const bool show)=0
Shows or hides an item.
virtual void delete_item(const unsigned index)=0
Deletes an item.
boost::dynamic_bitset get_items_shown() const
Returns the visibility of all the items as a bit set.
virtual void handle_key_up_arrow(SDL_Keymod modifier, bool &handled)=0
Up arrow key pressed.
virtual void place(const point &origin, const point &size) override=0
See widget::place.
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=0
See widget::calculate_best_size.
virtual void handle_key_down_arrow(SDL_Keymod modifier, bool &handled)=0
Down arrow key pressed.
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.
void toggle_item(const unsigned index)
Toggles the selection state of an item.
virtual bool is_selected(const unsigned index) const =0
Returns whether the item is selected.
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 clear()=0
Deletes all items.
virtual int get_selected_item() const =0
Returns the selected item.
Basic template class to generate new items.
virtual void create_items(const int index, const builder_grid &list_builder, const std::vector< widget_data > &data, const std::function< void(widget &)> &callback) override
Inherited from generator_base.
void set_active(const bool active)
Activates all children.
virtual bool has_widget(const widget &widget) const override
See widget::has_widget.
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.
void update_layout()
Updates internal layout.
void list_item_clicked(widget &caller)
Function to call after the user clicked on a row.
void mark_as_unsorted()
Deactivates all sorting toggle buttons at the top, making the list look like it's not sorted.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
void handle_key_right_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
void set_row_active(const unsigned row, const bool active)
Makes a row active or inactive.
std::vector< std::pair< selectable_item *, generator_sort_array > > orders_
void set_row_shown(const unsigned row, const bool shown)
Makes a row visible or invisible.
void handle_key_left_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
void order_by_column(unsigned column, widget &widget)
void resize_content(const int width_modification, const int height_modification, const int width_modification_pos=-1, const int height_modification_pos=-1)
Resizes the content.
void order_by(const generator_base::order_func &func)
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
void set_active_sorter(std::string_view id, sort_order::type order, bool select_first=false)
Sorts the listbox by a pre-set sorting option.
generator_base::placement placement_
virtual void set_content_size(const point &origin, const point &size) override
Inherited from scrollbar_container.
virtual void place(const point &origin, const point &size) override
See widget::place.
void update_visible_area_on_key_event(const KEY_SCROLL_DIRECTION direction)
Helper to update visible area after a key event.
void initialize_sorter(std::string_view id, generator_sort_array &&)
Implementation detail of set_single_sorter.
generator_base * generator_
Contains a pointer to the generator.
std::function< void(unsigned, sort_order::type)> callback_order_change_
bool select_row(const unsigned row, const bool select=true)
Selects a row.
bool update_content_size()
Request to update the size of the content after changing the content.
boost::dynamic_bitset get_rows_shown() const
Returns a list of visible rows.
std::size_t filter_rows_by(const std::function< bool(std::size_t)> &filter)
Hides all rows for which the given predicate returns false.
void handle_key_down_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
std::pair< widget *, sort_order::type > get_active_sorter() const
Returns a widget pointer to the active sorter, along with its corresponding order.
void remove_row(const unsigned row, unsigned count=1)
Removes a row in the listbox.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
unsigned get_item_count() const
Returns the number of items in the listbox.
bool select_row_at(const unsigned row, const bool select=true)
Selects a row at the given position, regardless of sorting order.
builder_grid_const_ptr list_builder_
Contains the builder for the new items.
bool row_selected(const unsigned row)
Check if a row is selected.
void handle_key_up_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
Small abstract helper class.
virtual unsigned get_value() const =0
Is the styled_widget selected?
bool get_value_bool() const
Helper class to block invalidate_layout.
base class of top level items, the only item which needs to store the final canvases to draw on.
void keyboard_capture(widget *widget)
void invalidate_layout()
Updates the size of the window.
static std::string _(const char *str)
Define the common log macros for the gui toolkit.
void point(int x, int y)
Draw a single point.
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
static std::vector< widget_data > parse_list_data(const config &data, const unsigned int req_cols)
std::array< generator_base::order_func, 2 > generator_sort_array
std::map< std::string, widget_item > widget_data
std::map< std::string, t_string > widget_item
void swap_grid(grid *g, grid *content_grid, std::unique_ptr< widget > widget, const std::string &id)
Swaps an item in a grid for another one.
Contains the implementation details for lexical_cast and shouldn't be used directly.
int icompare(const std::string &s1, const std::string &s2)
Case-insensitive lexicographical comparison.
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
constexpr std::underlying_type_t< Enum > to_underlying(Enum e) noexcept
Contains the SDL_Rect helper code.
std::vector< widget_data > list_data
Listbox data.
builder_grid_ptr list_builder
virtual std::unique_ptr< widget > build() const override
Inherited from builder_widget.
builder_listbox(const config &cfg)
static bool less(const T &lhs, const T &rhs)
static bool more(const T &lhs, const T &rhs)
resolution(const config &cfg)
listbox_definition(const config &cfg)
std::vector< state_definition > state
An abstract description of a rectangle with integer coordinates.
bool overlaps(const SDL_Rect &r) const
Whether the given rectangle and this rectangle overlap.
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
static map_location::direction s
std::string missing_mandatory_wml_tag(const std::string §ion, const std::string &tag)
Returns a standard message for a missing wml child (tag).
std::string missing_mandatory_wml_key(const std::string §ion, const std::string &key, const std::string &primary_key, const std::string &primary_value)
Returns a standard message for a missing wml key (attribute).
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE_WML_CHILD(cfg, key, message)
#define VALIDATE(cond, message)
The macro to use for the validation of WML.