The Battle for Wesnoth  1.19.7+dev
units_dialog.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2016 - 2024
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
18 #include "gui/widgets/button.hpp"
19 #include "gui/widgets/group.hpp"
20 #include "gui/widgets/listbox.hpp"
23 #include "team.hpp"
24 #include "units/ptr.hpp"
25 #include "units/types.hpp"
26 
27 #include <boost/dynamic_bitset/dynamic_bitset.hpp>
28 #include <string>
29 #include <vector>
30 
31 class team;
32 
33 namespace gui2::dialogs
34 {
35 
36 class units_dialog : public modal_dialog
37 {
38 public:
39  units_dialog();
40 
41  int get_selected_index() const
42  {
43  return selected_index_;
44  }
45 
46  bool is_selected() const
47  {
48  return selected_index_ != -1;
49  }
50 
51  /** Gender choice from the user. */
53  {
54  return gender_;
55  }
56 
57  /** Variation choice from the user. */
58  std::string variation() const
59  {
60  return variation_;
61  }
62 
64  {
65  variation_.clear();
66  }
67 
68  // } --------------- BUILDER HELPERS -------------- {
69 
70  units_dialog& set_title(const std::string& title)
71  {
72  title_ = title;
73  return *this;
74  }
75 
76  units_dialog& set_ok_label(const std::string& ok_label)
77  {
78  ok_label_ = ok_label;
79  return *this;
80  }
81 
82  units_dialog& set_cancel_label(const std::string& cancel_label)
83  {
84  cancel_label_ = cancel_label;
85  return *this;
86  }
87 
88  units_dialog& show_all_headers(const bool show = true)
89  {
91  return *this;
92  }
93 
94  units_dialog& show_header(std::string_view id, const bool visible = true)
95  {
96  find_widget<toggle_button>(id).set_visible(visible);
97  return *this;
98  }
99 
100  units_dialog& set_help_topic(const std::string& topic_id)
101  {
102  topic_id_ = topic_id;
103  return *this;
104  }
105 
106  units_dialog& set_row_num(const std::size_t row_num)
107  {
108  row_num_ = row_num;
109  return *this;
110  }
111 
112  /**
113  * Called to update the UI components, such as the preview pane, gender toggles
114  * and variation box.
115  */
116  units_dialog& set_update_function(const std::function<void(const std::size_t)>& update_func)
117  {
118  update_view_ = update_func;
119  return *this;
120  }
121 
122  /**
123  * Corresponding to each widget in the row with id 'id', there is a lambda that generates
124  * the corresponding label to set to that widget. This method sets those generator functions.
125  * The 'id's must be the same as those defined for the various widgets
126  * in the [list_definition] in the WML file.
127  */
128  template<typename Value, typename Generator = std::function<std::string(const Value&)>>
130  std::string_view id,
131  const std::vector<Value>& container,
132  const Generator& generator,
133  const bool use_as_sorter = false)
134  {
135  column_generators_.try_emplace(id, [&container, generator](std::size_t index) { return generator(container[index]); });
136  // use the generator function also as sorter function
137  if (use_as_sorter) {
138  find_widget<gui2::listbox>("main_list").set_single_sorter(
139  id, [&container, generator](std::size_t index) { return generator(container[index]); });
140  }
141  return *this;
142  }
143 
144  template<typename Value, typename Generator = std::function<std::string(const Value&)>
145  , typename Sorter = std::function<std::string(const Value&)>>
147  std::string_view id,
148  const std::vector<Value>& container,
149  const Generator& generator,
150  const Sorter& sorter)
151  {
152  column_generators_.try_emplace(id, [&container, generator](std::size_t index) { return generator(container[index]); });
153  find_widget<gui2::listbox>("main_list").set_single_sorter(
154  id, [&container, sorter](std::size_t index) { return sorter(container[index]); });
155  return *this;
156  }
157 
158  /**
159  * Sets the generator function for the tooltips
160  */
161  template<typename Value, typename Generator = std::function<std::string(const Value&)>>
163  const std::vector<Value>& container, const Generator& generator)
164  {
165  tooltip_gen_ = [&container, generator](std::size_t index) { return generator(container[index]); };
166  return *this;
167  }
168 
169  // } -------------------- BUILDERS -------------------- {
170 
171  static std::unique_ptr<units_dialog> build_create_dialog(const std::vector<const unit_type*>& types_list);
172  static std::unique_ptr<units_dialog> build_recruit_dialog(const std::vector<const unit_type*>& recruit_list, const team& team);
173  static std::unique_ptr<units_dialog> build_recall_dialog(std::vector<unit_const_ptr>& recall_list, const team& team);
174  static std::unique_ptr<units_dialog> build_unit_list_dialog(std::vector<unit_const_ptr>& units_list);
175 
176 private:
177  std::vector<unit_const_ptr> unit_list_;
178 
180  std::size_t row_num_;
181 
182  std::string title_;
183  std::string ok_label_;
184  std::string cancel_label_;
185  std::string topic_id_;
187 
188  std::map<std::string_view, std::function<std::string(std::size_t)>> column_generators_;
189  std::function<std::string(std::size_t)> tooltip_gen_;
190  std::function<void(const std::size_t)> update_view_;
191 
193  std::string variation_;
194 
195  std::vector<std::string> filter_options_;
196  std::vector<std::string> last_words_;
198 
200  return gender_toggle_;
201  }
202 
203  /** Callbacks */
204  void list_item_clicked();
205  void filter_text_changed();
206 
207  // FIXME only thing needing team
208  void dismiss_unit(std::vector<unit_const_ptr>& unit_list, const team& team);
209  void rename_unit(std::vector<unit_const_ptr>& unit_list);
210 
211  void show_list(listbox& list);
212  void show_help() const;
213 
214  void update_gender(const unit_race::GENDER val);
215  void update_variation();
216 
217  virtual const std::string& window_id() const override;
218 
219  virtual void pre_show() override;
220  virtual void post_show() override;
221 
222 };
223 
224 } // namespace gui2::dialogs
Abstract base class for all modal dialogs.
bool show(const unsigned auto_close_time=0)
Shows the window.
void show_list(listbox &list)
static std::unique_ptr< units_dialog > build_recruit_dialog(const std::vector< const unit_type * > &recruit_list, const team &team)
std::vector< std::string > filter_options_
units_dialog & set_ok_label(const std::string &ok_label)
units_dialog & show_all_headers(const bool show=true)
std::function< std::string(std::size_t)> tooltip_gen_
std::function< void(const std::size_t)> update_view_
virtual void post_show() override
Actions to be taken after the window has been shown.
void rename_unit(std::vector< unit_const_ptr > &unit_list)
std::string variation() const
Variation choice from the user.
units_dialog & show_header(std::string_view id, const bool visible=true)
units_dialog & set_help_topic(const std::string &topic_id)
units_dialog & set_update_function(const std::function< void(const std::size_t)> &update_func)
Called to update the UI components, such as the preview pane, gender toggles and variation box.
std::vector< std::string > last_words_
units_dialog & set_column(std::string_view id, const std::vector< Value > &container, const Generator &generator, const Sorter &sorter)
units_dialog & set_cancel_label(const std::string &cancel_label)
units_dialog & set_tooltip_generator(const std::vector< Value > &container, const Generator &generator)
Sets the generator function for the tooltips.
group< unit_race::GENDER > & get_toggle()
std::vector< unit_const_ptr > unit_list_
group< unit_race::GENDER > gender_toggle_
static std::unique_ptr< units_dialog > build_unit_list_dialog(std::vector< unit_const_ptr > &units_list)
units_dialog & set_row_num(const std::size_t row_num)
static std::unique_ptr< units_dialog > build_create_dialog(const std::vector< const unit_type * > &types_list)
void dismiss_unit(std::vector< unit_const_ptr > &unit_list, const team &team)
std::map< std::string_view, std::function< std::string(std::size_t)> > column_generators_
units_dialog & set_column(std::string_view id, const std::vector< Value > &container, const Generator &generator, const bool use_as_sorter=false)
Corresponding to each widget in the row with id 'id', there is a lambda that generates the correspond...
virtual const std::string & window_id() const override
The ID of the window to build.
virtual void pre_show() override
Actions to be taken before showing the window.
void list_item_clicked()
Callbacks.
unit_race::GENDER gender() const
Gender choice from the user.
units_dialog & set_title(const std::string &title)
static std::unique_ptr< units_dialog > build_recall_dialog(std::vector< unit_const_ptr > &recall_list, const team &team)
void update_gender(const unit_race::GENDER val)
Basic template class to generate new items.
The listbox class.
Definition: listbox.hpp:41
void set_visible(const visibility visible)
Definition: widget.cpp:479
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
rng * generator
This generator is automatically synced during synced context.
Definition: random.cpp:60
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.
Definition: unicode.cpp:70